From f4474c3dfdaceb3fda47ada5058d5bd697955d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20=F0=9F=94=B6=20Tarbert?= <66887028+NathanTarbert@users.noreply.github.com> Date: Thu, 8 Oct 2026 11:11:14 -0400 Subject: [PATCH 1/2] Ask before every command that can edit a folder "Always allow in this folder" now covers a Bot's read-only commands. A command that can edit files in an approved folder shows the desktop prompt every time, the prompt says so, and it no longer offers to stop asking for that command. Read-only commands in a folder already set to always allow behave as before. --- CHANGELOG.md | 7 +++ desktop/src-tauri/src/desktop_host_access.rs | 27 +++++++---- desktop/src-tauri/src/host_access.rs | 48 +++++++++++++++++--- 3 files changed, 66 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6863c3f0d..cbdbc7dc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged. ## Unreleased +### The desktop asks before every command that can edit a folder + +"Always allow in this folder" now covers a Bot's read-only commands. A command that can edit or +delete files in an approved folder shows the desktop prompt every time, and the prompt no longer +offers to stop asking for it. Folders already set to always allow keep that setting for read-only +commands. + ### A new deployment starts with two coworkers, not twelve The example package loaded every coworker in `examples/fintech/agents/`, so a fresh deployment opened diff --git a/desktop/src-tauri/src/desktop_host_access.rs b/desktop/src-tauri/src/desktop_host_access.rs index 44a261402..e2cf73d2d 100644 --- a/desktop/src-tauri/src/desktop_host_access.rs +++ b/desktop/src-tauri/src/desktop_host_access.rs @@ -1,7 +1,8 @@ //! Owner approval is collected by native dialogs, never by an app/tool-provided answer. use openbot_desktop_lib::host_access::{ - command_approval, ApprovedFolder, ChooseFolderPrompt, CommandApproval, CommandPrompt, - HostAccessError, HostAccessResult, HostApprovalUi, LocalCommandAllowList, WritePrompt, + command_approval, ApprovedFolder, ChooseFolderPrompt, CommandApproval, CommandPolicy, + CommandPrompt, HostAccessError, HostAccessResult, HostApprovalUi, LocalCommandAllowList, + WritePrompt, }; use tauri::Manager; use tauri_plugin_dialog::{ @@ -148,13 +149,14 @@ impl HostApprovalUi for NativeApproval { reviewable(&request.command)?; let list = self.allow_list()?; let allowed_here = list.allows(&request.bot_id, &request.root); - let offer_always = match command_approval(request.command_policy, allowed_here) { - CommandApproval::Refuse => { - return Err(refused("Commands on this computer are set to never run.")) - } - CommandApproval::Proceed => return Ok(()), - CommandApproval::Ask { offer_always } => offer_always, - }; + let offer_always = + match command_approval(request.command_policy, allowed_here, request.writable) { + CommandApproval::Refuse => { + return Err(refused("Commands on this computer are set to never run.")) + } + CommandApproval::Proceed => return Ok(()), + CommandApproval::Ask { offer_always } => offer_always, + }; let bot = bot_label(request.bot_name.as_deref(), &request.bot_id); let access = if request.writable { "This command may edit or delete files in the approved folder. Commands cannot be undone automatically." @@ -163,7 +165,12 @@ impl HostApprovalUi for NativeApproval { }; let setting = if offer_always { format!( - "Your OpenBot setting: {}. Choose \"{ALWAYS_HERE}\" to stop asking about {bot}'s commands in this folder on this computer.", + "Your OpenBot setting: {}. Choose \"{ALWAYS_HERE}\" to stop asking about {bot}'s read-only commands in this folder on this computer.", + request.command_policy.label() + ) + } else if request.writable && request.command_policy == CommandPolicy::Allow { + format!( + "Your OpenBot setting: {}. Commands that can edit files still ask every time.", request.command_policy.label() ) } else { diff --git a/desktop/src-tauri/src/host_access.rs b/desktop/src-tauri/src/host_access.rs index acf865158..7d47f4cf8 100644 --- a/desktop/src-tauri/src/host_access.rs +++ b/desktop/src-tauri/src/host_access.rs @@ -240,7 +240,8 @@ impl CommandPolicy { pub enum CommandApproval { /// Refused on this machine too, whatever the server let through. Refuse, - /// The person chose "always allow" for this Bot in this folder on this computer. + /// The person chose "always allow" for this Bot in this folder on this computer, and the + /// command leaves the folder read-only. Proceed, /// Show the dialog. `offer_always` adds "Always allow in this folder". Ask { offer_always: bool }, @@ -248,9 +249,18 @@ pub enum CommandApproval { /// The member's server setting gates the local one: a folder the person always allowed here is /// only honoured while their setting (after the team cap) is still "always allow". -pub fn command_approval(policy: CommandPolicy, allowed_here: bool) -> CommandApproval { +/// +/// "Always allow" covers read-only commands. A command that can edit the folder asks every time. +pub fn command_approval( + policy: CommandPolicy, + allowed_here: bool, + writable: bool, +) -> CommandApproval { match policy { CommandPolicy::Never => CommandApproval::Refuse, + CommandPolicy::Allow if writable => CommandApproval::Ask { + offer_always: false, + }, CommandPolicy::Allow if allowed_here => CommandApproval::Proceed, CommandPolicy::Allow => CommandApproval::Ask { offer_always: true }, CommandPolicy::Ask => CommandApproval::Ask { @@ -1765,26 +1775,52 @@ mod command_policy_tests { #[test] fn local_always_allow_only_counts_while_the_server_setting_allows() { assert_eq!( - command_approval(CommandPolicy::Never, true), + command_approval(CommandPolicy::Never, true, false), CommandApproval::Refuse ); assert_eq!( - command_approval(CommandPolicy::Allow, true), + command_approval(CommandPolicy::Allow, true, false), CommandApproval::Proceed ); assert_eq!( - command_approval(CommandPolicy::Allow, false), + command_approval(CommandPolicy::Allow, false, false), CommandApproval::Ask { offer_always: true } ); // An admin cap of "ask" pauses a folder the person always allowed. assert_eq!( - command_approval(CommandPolicy::Ask, true), + command_approval(CommandPolicy::Ask, true, false), CommandApproval::Ask { offer_always: false } ); } + #[test] + fn a_command_that_can_edit_the_folder_asks_even_where_always_allowed() { + assert_eq!( + command_approval(CommandPolicy::Allow, true, true), + CommandApproval::Ask { + offer_always: false + } + ); + assert_eq!( + command_approval(CommandPolicy::Allow, false, true), + CommandApproval::Ask { + offer_always: false + } + ); + assert_eq!( + command_approval(CommandPolicy::Ask, true, true), + CommandApproval::Ask { + offer_always: false + } + ); + assert_eq!( + command_approval(CommandPolicy::Never, true, true), + CommandApproval::Refuse + ); + } + #[test] fn the_local_allow_list_is_per_bot_and_folder_and_survives_reload() { let dir = std::env::temp_dir().join(fresh_id("allow-list")); From 1177227b1539fc57b2aefe89711e75c982b9c883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20=F0=9F=94=B6=20Tarbert?= <66887028+NathanTarbert@users.noreply.github.com> Date: Thu, 8 Oct 2026 17:09:34 -0400 Subject: [PATCH 2/2] Describe the folder prompt change in plainer words --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbdbc7dc0..f96c0cf11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,10 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged. ### The desktop asks before every command that can edit a folder -"Always allow in this folder" now covers a Bot's read-only commands. A command that can edit or -delete files in an approved folder shows the desktop prompt every time, and the prompt no longer -offers to stop asking for it. Folders already set to always allow keep that setting for read-only -commands. +When a Bot runs a command in a folder shared from the desktop app, the person sees a prompt that can +offer "Always allow in this folder". That choice now covers commands that only read the folder. A +command that can change or delete files in it shows the prompt every time, without the "Always +allow" option. Folders already set to "Always allow" work as before for read-only commands. ### A new deployment starts with two coworkers, not twelve