Add ACP path grants and permission policies - #597
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
There was a problem hiding this comment.
Pull request overview
Adds directory-grant (“where can the agent work”) and operation confirmation policy (“what can it do”) plumbing across WTA (Rust), Windows Terminal protocol routing (C++), and Settings UI/localization, enabling persistent allowed host directories and policy-driven ACP permission resolution.
Changes:
- Introduces ACP permission policy evaluation and session/global directory grant handling in WTA, plus
/add-dir,/remove-dir,/list-dirscommand hooks. - Adds protocol event routing for allowed-directory updates and a new global setting
aiIntegration.allowedDirectories.host. - Extends Settings Editor UI/resources and WTA locale strings for the new directory grant/policy UX.
Reviewed changes
Copilot reviewed 147 out of 147 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/wta/src/ui/permission.rs | Renders permission targets, preferring stored grant directory when present. |
| tools/wta/src/protocol/acp/prompt_context.rs | Exposes pane resolution helper for reuse. |
| tools/wta/src/protocol/acp/mod.rs | Registers new ACP permission policy module. |
| tools/wta/src/main.rs | Wires CLI args into helper config (policies + allowed dirs) and adds path_grants module. |
| tools/wta/src/helper/runtime.rs | Constructs and passes operation policies + session roots to ACP client/app state. |
| tools/wta/src/helper/config.rs | Adds helper runtime config fields for policies and allowed directories. |
| tools/wta/src/event.rs | Forwards right-click mouse down events (used by new UX interactions). |
| tools/wta/src/commands.rs | Adds /add-dir ghost-default parsing helper and new command registrations. |
| tools/wta/src/cli/args.rs | Adds hidden CLI args for confirmation policy and allowed directory roots. |
| tools/wta/src/autofix_tests.rs | Formatting-only test updates. |
| tools/wta/src/app/turn_state.rs | Minor formatting-only update. |
| tools/wta/src/app/tab_state.rs | Extends permission/chat state to support new policy/grant metadata. |
| tools/wta/src/app/input_edit.rs | Minor formatting-only update. |
| tools/wta/src/app/autofix.rs | Minor formatting-only update. |
| tools/wta/src/app/attachments.rs | Minor formatting-only update. |
| tools/wta/src/app_contracts/permission.rs | Adds explicit option-kind constants + helpers for directory grant options. |
| tools/wta/src/app_contracts/mod.rs | Re-exports new permission constants. |
| tools/wta/src/app_contracts/event.rs | Adds new app events and permission payload fields for policy/grant UX. |
| tools/wta/locales/en-US.yml | Adds user-facing strings for ACP path grants + permission policy UI. |
| tools/wta/locales/en-GB.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/zh-CN.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/zh-TW.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/vi-VN.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/uz-Latn-UZ.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/uk-UA.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/tt-RU.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/tr-TR.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/sv-SE.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/sr-Latn-RS.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/sl-SI.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/sk-SK.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ru-RU.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ro-RO.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/qps-ploc.yml | Adds pseudo-locale strings for path grants + permission policy UI. |
| tools/wta/locales/qps-ploca.yml | Adds pseudo-locale strings for path grants + permission policy UI. |
| tools/wta/locales/qps-plocm.yml | Adds pseudo-locale strings for path grants + permission policy UI. |
| tools/wta/locales/pt-BR.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/pt-PT.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/pl-PL.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/nn-NO.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/nl-NL.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/nb-NO.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ms-MY.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/lb-LU.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ko-KR.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/it-IT.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/is-IS.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/id-ID.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/he-IL.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/gl-ES.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/fr-FR.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/fr-CA.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/fi-FI.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/fa-IR.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/eu-ES.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/et-EE.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/es-ES.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/es-MX.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/de-DE.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/da-DK.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/cs-CZ.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ca-ES.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ca-Es-VALENCIA.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/bs-Latn-BA.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/az-Latn-AZ.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/ar-SA.yml | Adds locale strings for path grants + permission policy UI. |
| tools/wta/locales/af-ZA.yml | Adds locale strings for path grants + permission policy UI. |
| src/cascadia/WindowsTerminal/TerminalProtocolComServer.h | Adds dispatcher entry point for allowed-directory update events. |
| src/cascadia/WindowsTerminal/TerminalProtocolComServer.cpp | Implements dispatch of allowed-directory update events to UI thread. |
| src/cascadia/TerminalSettingsModel/MTSMSettings.h | Adds aiIntegration.allowedDirectories.host and updates confirmation defaults. |
| src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl | Adds AiAllowedHostDirectories setting to the model. |
| src/cascadia/TerminalProtocol/ProtocolParsing.h | Routes update_allowed_directory events to a dedicated page handler. |
| src/cascadia/TerminalApp/TerminalPage.idl | Adds page handler for allowed-directory update requests. |
| src/cascadia/TerminalApp/TerminalPage.h | Adds runtime snapshot field for allowed host directories. |
| src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.idl | Adds view-model surface for allowed host directory list management. |
| src/cascadia/TerminalSettingsEditor/AIAgentsViewModel.h | Adds AllowedDirectoryEntry and backing state/methods for directory management. |
| src/cascadia/TerminalSettingsEditor/AIAgents.xaml | Adds settings UI to view/add/remove allowed host directories. |
| src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/de-DE/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/es-ES/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/fr-FR/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/it-IT/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/ja-JP/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/ko-KR/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/pt-BR/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/qps-ploc/Resources.resw | Adds pseudo-locale strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/qps-ploca/Resources.resw | Adds pseudo-locale strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/qps-plocm/Resources.resw | Adds pseudo-locale strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/ru-RU/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/sr-Cyrl-RS/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/uk-UA/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/zh-CN/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| src/cascadia/TerminalSettingsEditor/Resources/zh-TW/Resources.resw | Adds localized strings for the new allowed-directory settings UI. |
| doc/security-model.md | Updates security model doc with new spec reference (needs status refresh). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 147 out of 147 changed files in this pull request and generated no new comments.
Suppressed comments (2)
doc/security-model.md:409
- This mitigation table entry is now out of date: the WTA ACP client does enforce read/create/input confirmation policies at runtime (via
permission_policy::evaluate), and the default settings values are no longer “all auto” sincecreateOperations/inputOperationsnow default topromptinMTSMSettings.h. Please update these rows so the security model reflects the current implementation.
| Implement runtime confirmation enforcement for sensitive read/create/input operation classes | Not implemented; settings-model knobs exist but are not wired to runtime authorization. Proposed design: [`ACP path grants and permission policy`](./specs/acp-path-grants-and-permission-policy.md). | Prompt injection, settings persistence |
| After enforcement exists, default `aiIntegration.confirmation.{read,create,input}Operations` to `prompt` on fresh install (all three currently default to `auto` per `MTSMSettings.h`) | Not implemented | Prompt-injection blast radius |
tools/wta/locales/de-DE.yml:95
- These new permission UI strings are still in English in the de-DE locale (and appear to be English in multiple other non-English locales), which is inconsistent with the surrounding translated content. Either translate them for this locale or intentionally keep them as English with a clear rationale/locking pattern across all locales.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 149 out of 149 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/cascadia/TerminalApp/TerminalPage.cpp:5613
isAbsoluteHostPathtreats any\\<something>\<something>as a valid UNC path, which also accepts device/extended prefixes like\\.\and\\?\.... That would allow adding device-namespace paths as allowed directories. Tighten the UNC validation by rejecting.and?as the server component (so only real\\server\share-style roots are accepted).
const auto separator = value.find_first_of(L"\\/", 2);
return separator != std::wstring_view::npos &&
separator > 2 &&
separator + 1 < value.size() &&
!isSeparator(value[separator + 1]);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 149 out of 149 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
tools/wta/src/protocol/acp/client.rs:2751
additional_directoriesis anOption<bool>, sois_some()treats an explicitSome(false)as supported. Copilot currently advertisesadditionalDirectories=false; this path will therefore send roots despite the capability gate and contradicts the documented compatibility behavior. Use the advertised boolean value and add aSome(false)capability test.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 151 out of 151 changed files in this pull request and generated no new comments.
Suppressed comments (3)
tools/wta/src/app_keys.rs:35
- This lookup references
path_grants.session_added, but no locale defines that key; the existing localized success key ispath_grants.added. Selecting “This session” will therefore surface a missing-key fallback instead of the intended message.
tools/wta/src/app_keys.rs:47 path_grants.update_failedis not defined in any locale. Reuse the existingpath_grants.failedkey so storage errors produce a localized warning rather than a missing-key fallback.
src/cascadia/TerminalApp/TerminalPage.cpp:5709WriteSettingsToDisk()reports failure by returningfalse(it catches write exceptions internally), so thistryblock currently publishes success and approves the pending ACP request even when the global grant was not persisted. Check the return value and enter the rollback path onfalse.
globals.AiAllowedHostDirectories(updated);
_settings.WriteSettingsToDisk();
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 151 out of 151 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
tools/wta/src/app.rs:4553
get_active_paneis process-global and resolves the most-recent window, not this helper's owning tab. If focus moves to another tab/window while this async lookup is in flight,/add-dirdisplays and accepts that other pane's cwd. Resolve the helper's capturedsource_session_id(the existing resolver was madepub(crate)in this PR), falling back to the active-pane query only when no source pane was captured.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 152 out of 152 changed files in this pull request and generated no new comments.
Suppressed comments (6)
tools/wta/src/app_keys.rs:47
path_grants.update_failedis absent from every locale, so a failed session-grant selection displays a missing localization key. Reuse the existing localized failure key.
tools/wta/src/app/tab_state.rs:360- This new set is not cleared by
TabSession::clear_chat_history()even though the adjacenttool_callsstate is. After/new, restart, or session resume clears the chat, a reused tool-call ID can therefore be incorrectly labeled as auto-approved in the next session; clear this set at the same lifecycle boundaries.
tools/wta/src/protocol/acp/client.rs:2751 - This capability check treats
Some(false)as support. Copilot 1.0.79 explicitly reportsadditionalDirectories=false, so this still sends unsupported roots and reports the capability as enabled, contrary to the PR compatibility contract. Test the advertised boolean value rather than only its presence.
src/cascadia/TerminalSettingsModel/MTSMSettings.h:93 GlobalAppSettings::Copy()shallow-copies macro-backed fields, then explicitly deep-copies each mutableIVector<hstring>(DisabledProfileSourcesandSafeUriSchemesatGlobalAppSettings.cpp:106-120). This new vector is not deep-copied, so copied settings objects share one mutable allowed-directory collection and anAppend/Removethrough either copy can mutate the other.
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, AiAllowedHostDirectories, "aiIntegration.allowedDirectories.host", winrt::single_threaded_vector<winrt::hstring>()) \
tools/wta/src/app_keys.rs:35
- This localization key does not exist in any WTA locale, so choosing “This session” surfaces a missing-key fallback instead of the success message. The already-localized
path_grants.addedkey is used by/add-dirfor the same outcome.
This issue also appears on line 47 of the same file.
tools/wta/src/path_grants.rs:658
- Host-path equality does not normalize
/to\, although the documented Settings contract says the separators are equivalent. Consequently/remove-dir C:/workcannot remove a storedC:\workgrant, and slash variants can be persisted as duplicate session roots.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 152 out of 152 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/cascadia/TerminalApp/TerminalPage.cpp:2453
- Every configured root is serialized onto the Windows helper command line, but the setting has no count or aggregate-length bound. A single long-path value (or enough ordinary roots) can exceed CreateProcess's 32,767-character command-line limit and prevent the agent pane from starting. Pass the initial list through a bounded file/protocol payload, or enforce an aggregate limit before persisting it.
for (const auto& directory : globals.AiAllowedHostDirectories())
{
appendHelperFlagValue(L"--allowed-directory", directory);
tools/wta/src/app_keys.rs:47
path_grants.update_failedis not defined in the locale catalogs; the existing error key ispath_grants.failed. A failed session grant currently displays a missing-key fallback.
tools/wta/src/app_keys.rs:35- This key does not exist in any locale; the defined session-grant success key is
path_grants.added. Selecting “This session” will therefore surface an untranslated/missing-key fallback instead of the success message.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 152 out of 152 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
tools/wta/src/app_keys.rs:47
path_grants.update_failedis absent from every locale; the defined failure key ispath_grants.failed. As written, a failed session-grant action displays the untranslated/missing key.
tools/wta/src/helper/runtime.rs:530- The confirmation policies are copied into an immutable
OperationPoliciesonly when the helper starts. Settings reload hot-propagates allowed directories but neither rebuilds the helper forAiConfirmation*Opschanges nor carries them inagent_config_changed, so changing read fromautotoprompt/denyleaves existing sessions auto-approving under the old policy. Hot-update these policies or include them in the helper-rebuild snapshot.
src/cascadia/TerminalApp/TerminalPage.cpp:5710 WriteSettingsToDisk()catches write exceptions internally and returnsfalse(CascadiaSettingsSerialization.cpp:1622-1640), so thistryblock publishes success and approves the pending ACP request even when the directory was not persisted. Check the return value and run the existing rollback/failure path onfalse.
globals.AiAllowedHostDirectories(updated);
_settings.WriteSettingsToDisk();
}
tools/wta/src/app_keys.rs:35
- This localization key does not exist in any WTA locale (including
en-US.yml), so selecting “This session” surfaces a missing-key fallback instead of the success message. Use the existingpath_grants.addedkey or addsession_addedto every locale.
This issue also appears on line 47 of the same file.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 150 out of 150 changed files in this pull request and generated no new comments.
Suppressed comments (6)
tools/wta/src/app_keys.rs:47
path_grants.update_failedis absent from every locale, so a storage failure displays the resource key rather than the localized error. The existingpath_grants.failedkey has the same interpolation contract.
tools/wta/src/app_keys.rs:35path_grants.session_addedis not defined in any locale, includingen-US.yml, so choosing “This session” surfaces the untranslated key instead of a success message. Reuse the existing localizedpath_grants.addedmessage.
This issue also appears on line 47 of the same file.
src/cascadia/TerminalSettingsModel/MTSMSettings.h:93
- Adding a mutable
IVectorhere also requires deep-copy handling inGlobalAppSettings::Copy. The macro copy atGlobalAppSettings.cpp:69-71only copies the interface reference; existing vector settings are then cloned explicitly at lines 106-120. Without equivalent handling, a copied settings object and its source share this directory vector, so mutating the vector through either object unexpectedly changes both.
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, AiAllowedHostDirectories, "aiIntegration.allowedDirectories.host", winrt::single_threaded_vector<winrt::hstring>()) \
tools/wta/src/app/tab_state.rs:387
- This map is written for every tool call but is never read anywhere, is only removed for hidden calls, and is not cleared by
clear_chat_history. A long-lived helper therefore retains an unbounded duplicate of every tool-call ID/title/status. Remove this field and its insert/remove writes, or add a concrete consumer and lifecycle cleanup.
doc/specs/acp-path-grants-and-permission-policy.md:205 - The implementation sends both initial and hot permission configuration through
agent_config_changed; the hidden argv options are only legacy safe fallbacks. This diagram currently documents the obsolete argv path as the initial source.
├─ helper argv: initial roots + operation policies
└─ agent_config_changed: hot global-root updates
doc/specs/acp-path-grants-and-permission-policy.md:221
- The active settings propagation event is
agent_config_changed(TerminalPage.cpp:1788, handled inapp_events.rs:1400), notallowed_directories_changed. Keeping the old event name here makes the implementation guide misleading.
Settings changes are broadcast as `allowed_directories_changed` so active
helpers refresh their local policy. The generic COM `SendEvent` surface is
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24dce15b-d355-4c81-a5b0-773c925d5382
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 150 out of 150 changed files in this pull request and generated no new comments.
Suppressed comments (2)
tools/wta/src/app_keys.rs:48
- These two translation keys are not defined in any WTA locale, so choosing “This session” will surface a missing-key fallback instead of localized success/failure text. Reuse the existing
path_grants.addedandpath_grants.failedkeys (or add both new keys to every locale).
doc/security-model.md:414 - This “Implemented” entry conflicts with the security model earlier in the same document: §5.1 still says the
aiIntegration.confirmation.*settings “are not a present enforcement control,” and §5.2 describes confirmation knobs as potentially unenforced. Update those statements now that this PR wires runtime enforcement, otherwise readers receive contradictory security guarantees.
| Enforce runtime confirmation policy for sensitive read/create/input operation classes | Implemented; see [`ACP path grants and permission policy`](./specs/acp-path-grants-and-permission-policy.md). | Prompt injection, settings persistence |
| Use path-scoped `auto` for read operations and `prompt` for create/input operations on fresh installs | Implemented in `MTSMSettings.h` | Prompt-injection blast radius |
Summary
additionalDirectorieswhen the agent advertises supportDirectory UX
/add-dir <path>and/remove-dir <path>modify only the current ACP Session/add-dirsuggests the active source pane's working directory; Enter, Tab, and right-click accept the ghost text/remove-diropens a searchable, keyboard-selectable popup containing the current Session grants/list-dirsshows effective global and Session roots in a structured transcript card, omitting empty sectionsTranscriptCardStylewith shared wrapping, padding, width capping, indentation, Unicode alignment, and narrow-pane behaviorPermission semantics
Directory grants define where an agent may work. Operation policies independently define what it may do:
readOperationscreateOperationsinputOperationsA directory grant is not shell approval and is not an OS sandbox. The defaults remain read=
auto, create=prompt, and input=prompt.Session grants are keyed by agent, environment, and ACP Session. Global grants are authoritative in
aiIntegration.allowedDirectories.host.ACP compatibility
ACP exposes a stable primary
cwdplus capability-gatedadditionalDirectorieson Session lifecycle requests; it does not define a mid-Session root-mutation RPC. Intelligent Terminal therefore applies local permission changes immediately and sends the effective roots to the Agent on a latersession/neworsession/load.Copilot CLI 1.0.79 currently advertises
additionalDirectories=false. In that case Intelligent Terminal still persists and enforces the grants locally, and/list-dirsclearly explains that the Agent cannot receive the extra roots through ACP.Documentation
doc/specs/acp-path-grants-and-permission-policy.mddocuments the implementation, ownership boundaries, persistence, protocol flow, and security semanticsdoc/reference/agent-workspace-models.mdcompares Intelligent Terminal with Zed, JetBrains, Qt Creator, CodeCompanion, and WarpValidation
cargo test --target x86_64-pc-windows-msvc --manifest-path tools\wta\Cargo.toml --quiet(1512 passed)cargo build --target x86_64-pc-windows-msvc --manifest-path tools\wta\Cargo.tomltools\razzle.cmd && bcz no_clean