GUI Full access risk confirmation
GUI Full access 风险确认
Switching the web client to `danger-full-access` was a single click on a permission picker, with the preset shown as the title-cased machine name `Danger Full Access`. Full access reduces confirmation steps and lets the agent run sensitive operations, modify files, or execute external commands, so an accidental pick armed the most dangerous preset with no deliberate acknowledgement step.
English
Problem
Switching the web client to danger-full-access was a single click on a permission picker, with the preset shown as the title-cased machine name Danger Full Access. Full access reduces confirmation steps and lets the agent run sensitive operations, modify files, or execute external commands, so an accidental pick armed the most dangerous preset with no deliberate acknowledgement step.
Decision
Every permission picker gates danger-full-access behind the shared in-page RiskConfirmation dialog whose enabling action stays disabled until an explicit acknowledgement checkbox is checked; the preset renders under the product label Full access; every dismissal path submits nothing.
RiskConfirmation(ui-primitives) is a controlled Modal composition: title, description, acknowledgement checkbox, cancel, and a confirm button disabled untilacknowledged. It stays an in-page dialog — the Modal portals to this document's body and never opens a native or separate browser window that could land on another display.Modalgains acontentClassNameseat so the warning body scrolls inside constrained mobile/landscape viewports while the action row stays fixed.- The composer chip (
PermissionSelect, ui-conversation) intercepts a Full-access pick before the/permissionsubmit:confirmation/acknowledgedcomponent state opens the dialog, confirm submits/permission danger-full-accessthrough the same injectedcommandpath as every other pick, and cancel/Escape/close/mask leave the current preset untouched with the checkbox reset. The confirmation revokes itself when the session locks (locked/value-absent effect) and resets across task switches (key={sessionId}remount). Copy rides the standardconversationlocale seat asaccess.confirm.*keys. - The
/permissionpopup (ui-permission over the ui-commands shell) gates through data, not a second dialog implementation:SelectOptiongrows an optionalconfirmationpayload, the popup controller owns theconfirming/acknowledgedstate transitions, andPopupSelectViewswaps the picker card for the sameRiskConfirmationwhile a gated option is pending. - The General-settings Permission row uses the same controlled
RiskConfirmationbefore persisting Full access as the default for later sessions. Its warning names that future-session lifetime; cancel, Escape, close, and mask dismissal leave the stored default untouched. Full accessintentionally overrides the kebab-to-title display transform in every picker; command and Settings writes keep the machine name on the wire, and each warning body remains locale-aware in Chinese and English.
Alternatives considered
A native/OS or separate-window confirmation. Rejected: the dialog must stay inside the current WebUI window; a second window can appear on another display and detaches the decision from the page state it guards.
One shared locale namespace for every surface's safety copy. Rejected: the ui-permission bundle and ui-conversation load independently, while the Settings warning names a different future-session lifetime. Each bundle owns its copy, and ui-permission keeps the popup and Settings dictionaries separate rather than importing across bundle boundaries.
Gating in the host/permission backend. Out of scope by design: the change is browser-client confirmation flow only; backend permission semantics, defaults, and the safer presets' one-click behavior are unchanged.
Consequences
Every visible GUI path into Full access requires a deliberate, informed acknowledgement, at the cost of one extra dialog step for users who genuinely want the preset. New pickers reuse the shared dialog through their owning state machine or attach a confirmation payload to the popup path. Acceptance: the composer flow's gated cases in input-bar.spec.tsx, the popup gate in popup-view.spec.tsx and popup.spec.ts, the default-setting gate in permission-row.spec.tsx, the Modal/RiskConfirmation contract in atoms.spec.tsx, and the assembled Web replays.
中文
问题
在 Web 客户端的权限选择器中切换到 danger-full-access 只需一次点击,且预设以 Title Case 机器名 Danger Full Access 展示。Full access 会减少确认步骤,允许 agent(智能体)执行敏感操作、修改文件或运行外部命令,误点即在毫无刻意确认环节的情况下启用了最危险的预设。
决策
每个权限选择器都把 danger-full-access 关进共享的页面内 RiskConfirmation 对话框:启用按钮在用户勾选明确的风险确认复选框前保持禁用;预设以产品标签 Full access 展示;所有取消路径都不作任何提交。
RiskConfirmation(ui-primitives)是受控的 Modal 组合:标题、说明、确认复选框、取消,以及acknowledged勾选前禁用的确认按钮。它始终是页面内对话框——Modal portal 到本文档 body,绝不打开可能落在另一块显示器上的原生或独立浏览器窗口。Modal新增contentClassNameslot,令警示正文在受限的移动端/横屏视口内滚动,动作行保持固定。- composer chip(ui-conversation 的
PermissionSelect)在/permission提交前拦截 Full-access 选择:confirmation/acknowledged组件状态打开对话框,确认后经与其他选择完全相同的注入command通道提交/permission danger-full-access;取消、Escape、关闭与遮罩点击均保持当前预设不变并重置复选框。会话锁定时确认自行撤销(locked/值缺席 effect),切换任务时随key={sessionId}重挂载而重置。文案经标准conversationlocale slot 以access.confirm.*键供给。 /permissionpopup(ui-permission 构建于 ui-commands 外壳之上)以数据而非第二套对话框实现完成把关:SelectOption新增可选的confirmation载荷,popup 控制器拥有confirming/acknowledged状态迁移,PopupSelectView在门控选项未决期间把选择卡换成同一个RiskConfirmation。- 「通用」设置中的「权限」行在把 Full access 持久化为后续会话的默认值前,也使用同一个受控
RiskConfirmation。警示会明确说明该设置只影响后续会话;取消、Escape、关闭与点击遮罩均不会改动已存默认值。 Full access在每个选择器中都有意覆盖 kebab 转 Title Case 的显示变换;命令与 Settings 写入在 wire 上保留机器名,每份警示正文都保持中英文 locale 感知。
考虑过的替代方案
原生/操作系统或独立窗口确认。 已拒:对话框必须留在当前 WebUI 窗口内;第二个窗口可能出现在另一块显示器上,使决策脱离其守护的页面状态。
**每个界面的安全文案共享一个 locale namespace。**不予采用:ui-permission bundle 与 ui-conversation 可独立加载,而 Settings 警示说明的是另一种只影响后续会话的生效周期。每个 bundle 各自拥有文案,ui-permission 也将 popup 与 Settings 词典分开,而非跨 bundle 边界 import。
在 host/权限后端把关。 设计上即出界:本变更只涉浏览器客户端确认流;后端权限语义、默认值与更安全预设的一键行为均不变。
后果
进入 Full access 的每条可见 GUI 路径现在都要求刻意且知情的确认,代价是真想启用该预设的用户多一步对话框。新的选择器通过各自拥有的状态机复用共享对话框,或在 popup 路径挂 confirmation 载荷。验收:input-bar.spec.tsx 中编辑器流的门控用例、popup-view.spec.tsx 与 popup.spec.ts 的 popup 门、permission-row.spec.tsx 的默认设置门控、atoms.spec.tsx 的 Modal/RiskConfirmation 约定,以及组装态 Web 回放。