diff --git a/.doc/system-design/2026-09-15-multi-intent-hitl-plan.md b/.doc/system-design/2026-09-15-multi-intent-hitl-plan.md index 4d415daf..f858bb53 100644 --- a/.doc/system-design/2026-09-15-multi-intent-hitl-plan.md +++ b/.doc/system-design/2026-09-15-multi-intent-hitl-plan.md @@ -205,14 +205,18 @@ V2 灰度不可绕过:只有 ActionRegistry 映射稳定、V2 shadow 达门槛 ### 7.1 服务端权威卡片 -`PLAN_CONFIRM` 默认先展示一句自然语言摘要和主按钮,步骤细节按需展开,避免把 risk/action key 直接变成用户负担;展开后展示 plan/revision/digest 短码、步骤、依赖、动作、目标、风险、可见副作用、非原子失败语义、过期时间。支持全部确认、依赖闭包内部分确认、编辑、取消。 +`PLAN_CONFIRM` 折叠态也必须显示任务数、受影响目标、生成/写入/控制类型、最高风险、不可撤销副作用和“逐步提交、后续失败不回滚”提示;高风险步骤始终逐项可见。只有 action key、revision、digest 等技术元数据和低风险细节可折叠。支持全部确认、依赖闭包内部分确认、编辑、取消。 `CLARIFY_AGGREGATE` 展示逐步缺槽、约束、已知值和冲突。回复形成 slot patch 后必须重新识别、重新计算 digest、风险和授权预检。 用户只回答部分问题时保存可唯一映射的增量 patch,产生新 revision 并继续停留在 awaiting_clarification;新卡同时显示已解决值和剩余问题,旧卡 stale。不会要求重填已经验证的值,也不会在缺槽未闭合时提前执行。 +澄清字段按步骤和依赖分组,标记“已验证/待填写/冲突/无效”,显示剩余数量;提交文案为“保存已填写并继续”,提交后保留合法值并聚焦首个未解决字段。 + 卡片 metadata 是 PG 状态投影。按钮和自然语言“确认/取消/只做第 1 项”统一进入服务端 `DecidePlan`;前端不得本地修改业务资源或先标成功。 +部分确认 UI 使用依赖层级列表:选择子步骤时立即勾选并解释必需前置;存在已选后代时不能取消前置;提交按钮显示本次确认的步骤数和目标。未选项标为“继续等待”,显式排除是独立次级动作,并在提交前列出会被取消或阻塞的后代。 + 自然语言决策采用确定性语法优先:明确 plan/步骤编号或当前会话只有一个活动可见计划时才可绑定;“确认”在多个活动计划、步骤引用不合法或同时包含新任务时不执行,改为定向澄清。聚合槽位优先使用结构化卡片字段;自由文本只把可唯一映射的 `label:value`/已有 PatchSlots 结果写入 patch,冲突值、依赖值无效或多义值保持未解析并再次提问,绝不猜测。 ### 7.2 确认不等于授权 @@ -282,6 +286,10 @@ decision API 继承当前服务端认证方式、Origin/CSRF 策略和统一限 刷新时由 plan 表生成卡片/进度,不从旧按钮或 SSE 推断。页面刷新、重开、SSE 重连均以 GET 覆盖本地缓存。卡片需支持键盘/读屏、依赖说明、错误焦点、过期/陈旧状态;按钮提交后可显示 submitting,但只有服务端 receipt 能变为 executing/resolved。完整结果从 owning API 读取,SSE 只携安全摘要和版本。 +状态恢复矩阵:submitting 锁定重复提交并保留选择;outdated/conflict 自动读取最新 PlanView、聚焦状态通知并提供“查看最新版”;expired 禁用原决策,保留只读摘要并提供“按当前上下文重建计划”;服务端字段错误保留未提交输入并聚焦对应字段。会话顶部提供可关闭但可重新发现的活动计划入口,无活动计划返回明确空态。 + +可访问性契约:步骤用有序列表和带 legend 的选择组;折叠控件暴露 `aria-expanded/aria-controls`;进度用 polite live region,阻断错误用 alert 并聚焦;状态不只靠颜色;键盘顺序为摘要、步骤、主/次动作;窄屏单列、无横向滚动、触控目标至少 44px,并支持 reduced-motion。 + --- ## 十、灰度、指标与回滚 @@ -358,8 +366,8 @@ LLM 分段独立开关且从 shadow 起步。关闭新计划创建后,已有 **目标:** 按钮/自然语言走同一服务端命令,执行前重新授权。 **依赖:** U3。 **文件:** `internal/server/*intent_plan*`、`internal/app/intentflow/*`、授权端口契约、fake/dry-run adapter、auth integration tests。 -**做法:** GET/decision、错误信封、四元作用域、expected revision、依赖闭包、资源版本;不在本单元接真实业务属主 adapter。 -**测试:** 非成员/跨项目/跨 session;角色撤销;资源变更;stale revision;重复点击;非法部分确认;edit 使旧卡失效;按钮/自然语言同 receipt。 +**做法:** active discovery/GET/decision、错误信封、四元作用域、expected revision、依赖闭包、资源版本;不在本单元接真实业务属主 adapter。 +**测试:** 投影缺失仍能发现活动计划;非成员/跨项目/跨 session;角色撤销;资源变更;stale revision;重复点击;非法部分确认;edit 使旧卡失效;按钮/自然语言同 receipt。 **停走门:** 权限负例全绿;确认前零副作用;无系统身份绕过。 **mutex:** `intent-plan` + `server/authz`;动作接入另占 owner mutex。 @@ -369,7 +377,7 @@ LLM 分段独立开关且从 shadow 起步。关闭新计划创建后,已有 **依赖:** U4、U5。 **文件:** `web/src/types/workbench.ts`、`web/src/components/chat/InteractiveCard.tsx`、API client、`web/src/App.tsx`、web/browser tests。 **做法:** 两卡、步骤进度、依赖选择、submitting/outdated/expired/conflict、GET reconcile;计划动作不进入本地 AST/资源修改路径。 -**测试:** reload/reopen;双标签确认/取消;409;过期;键盘/读屏;SSE 重复乱序;慢请求。 +**测试:** reload/reopen 与无投影 active discovery;双标签确认/取消;409 查看最新版;过期重建;字段输入保留;键盘/读屏/live-region;窄屏 44px/reduced-motion;SSE 重复乱序;慢请求;validated_only 明示未执行。 **停走门:** 真实浏览器双标签/reload 无本地假成功。 **mutex:** `web`。 @@ -455,7 +463,7 @@ Definition of Done: ## 十三、关键决策 1. 采用 `app/intentflow` 深模块,不继续膨胀 coordinator; -2. 单意图生成行为保持,多意图用 ActionSpec 同源批量确认字段; +2. 单意图生成行为保持;多意图策略由 intentflow 的 BatchActionPolicy 管理并引用 ActionRegistry action key,不把应用编排政策回灌 L1; 3. 同步权威状态 + outbox 投影,不用纯事件驱动 plan state; 4. 服务端绝对过期,不用 TTLTurns 作权威; 5. 逐步骤事务,不制造跨 owner 长事务;