文档:接单化 review 收口第二轮写进 ADR、实施计划与共享记忆
- ADR 的后续更新补第二轮:§4 的拒单载荷 `kind` 收成 typed 枚举与并发拒单身份改成回合身份、§5 的回合身份口径覆盖拒单载荷、§6 的可留痕判据收掉 `ProjectRootUnanchored`、§7 的"同级提示"补上认不出的拒单 - 实施计划加「review 收口第二轮(2026-09-24)」一节,记下拒单表与界面提示口径的现状 - 决策记录追加同日第二条:五条决策、明确不做、两条待决策(连接收束时序、接单后落盘失败的双通道)与影响范围 / 验证证据
This commit is contained in:
@@ -1,5 +1,48 @@
|
||||
# 决策记录
|
||||
|
||||
## 2026-09-24 接单化 review 收口(第二轮):失败载荷分类、拒单身份与提示口径
|
||||
|
||||
- 决策(失败载荷的 `kind` 收成 typed 枚举):新增 `DirectTurnFailureKind`(`Serialize + Deserialize + TS`,
|
||||
`kebab-case`,7 个变体,含先前两份名单都漏登记的 `turn-interrupted`),`DirectTurnError::wire_kind`
|
||||
返回 `Option<DirectTurnFailureKind>`。线上仍是 `{kind, message}`、取值不变,只有 TS 侧从裸 `string`
|
||||
变成可穷尽收窄的联合类型;全仓没有按 `failure.kind` 分流的代码,它只给界面选语气。
|
||||
- 决策(并发拒单的两个身份是回合身份):`DirectThreadManager::accept_turn` 冲突时返回占用对象的
|
||||
`turn_id`,`DirectTurnReservation::accept` 把这一轮请求的 `clientTurnId` 传成
|
||||
`incoming_invocation_id`。改动前这两项是进程内 UUID,`TurnAlreadyRunning` 的"同一轮仍在处理中"
|
||||
分支永远命中不了,也与"回合身份由 `clientTurnId` 推导"的口径冲突。占用对象自己的 `token` 仍是
|
||||
UUID(`complete_direct_thread_turn_if_reserved` 靠它配对),只换错误载荷里的两项。
|
||||
- 决策(目录锚不定的拒单不再写诊断):`DirectTurnError::ProjectRootUnanchored` 从 `is_reportable()`
|
||||
拿掉,与 `ProjectRootUnusable` 同类——符号链接 / 权限 / 目录被删都是用户自己就能修的文件系统事实。
|
||||
改动前它被命令边界覆写成 `direct-codex-failure:v2` 收口文案,界面上那句"无法锚定 Direct 调用项目
|
||||
目录:{cause}"被内部诊断串顶掉;现在界面按 `Display` 显示,也不再进 `.agent/runtime/errors`。
|
||||
可留痕的拒单只剩 `environmentNotReady` / `hostStateUnavailable`。
|
||||
- 决策(认不出的拒单也要在聊天里有同级提示):`environmentNotReady` / `hostStateUnavailable` 除上报 +
|
||||
横幅外,再补一条与用户消息同级的提示——拒单没有接单、不产生 `turn.completed`,否则那条乐观用户
|
||||
气泡后面永远没有解释(改动前的注释"宿主已经把它放进了 `turn.completed.failure`"对拒单不成立)。
|
||||
文案走 `projectRuntimeVisibleRejectionError`:取宿主收口文案里已脱敏的摘要与建议,**不套阶段标签**
|
||||
(拒单这一轮没有开始,阶段只会是默认值);非结构化错误仍只走横幅(它可能发生在接单之后)。
|
||||
- 决策(失败说明的文案口径):`projectRuntimeVisibleError` 补上宿主 `Display` 事实句的模式
|
||||
(`执行通道已断开` / `等待模型回合结束达到硬上限` / `宿主任务提前结束` / `收尾历史失败` 一族),
|
||||
并给落盘那档补上不带"失败"二字的事实句;不回落宿主原文(`TransportClosed` 的原文带 `exitStatus=` /
|
||||
`stderrClass=`)。同时修掉收口文案的版本口径:解析只认 `v1`、宿主发的是多一段 `code=` 的 `v2`,
|
||||
脱敏摘要一直命中不了。口径定为"不加模式就只会看到通用文案",写在 `directTurnFailure.ts` 的注释里。
|
||||
- 明确不做:不改线上载荷形状与 `kind` 取值;不加新的失败阶段取值(拒单仍落默认阶段);不动
|
||||
`ProjectRootUnanchored` 之外的拒单分类。
|
||||
- 待决策(本轮没改代码,见交接清单):① "失败事实先于连接收束"的时序保证
|
||||
(`fail_game_creator_codex_app_server_connection` 先置 `inner.closed` 再 `record_execution_turn_failure`,
|
||||
200ms 看门狗可能抢先把它收束成 `Interrupted`);② 接单之后历史落盘失败仍从命令返回 `Err`,
|
||||
同一个失败经事件与命令两条通道下发(前端模型把 `Err` 当"这一轮没开始")。
|
||||
- 影响范围:Rust `apps/ai-game-creator-shell/src-tauri/src/agent/{direct_turn_error.rs,direct_turn_failure.rs,direct_turn_accept.rs,direct_thread_manager.rs,direct_runtime/user_input.rs}`;
|
||||
前端 `src/features/agent-runtime/model.ts`、`src/view/project-development/chat/{conversation/directCodexConversation.ts,conversation/directTurnFailure.ts,controller/useDirectProjectChatController.ts}`、
|
||||
`src/view/project-development/chat/generated/DirectTurnFailureKind.ts` 与
|
||||
`tests/{agentRuntimeModel.test.ts,directThreadChat.test.ts,appSurface/chat-composer.suite.ts,appSurface/project-conversation.suite.ts}`;
|
||||
文档 `docs/adr/【ADR】DirectProject命令接单化-2026-09-23.md`、`docs/technical/【实施计划】DirectProject命令接单化-2026-09-23.md`。
|
||||
- 验证:Rust `cargo test --bins "agent::"`(900 passed / 5 ignored)、定向
|
||||
`cargo test --bins "agent::direct_turn_error"`(15 passed)、`cargo fmt`;前端
|
||||
`npx vitest run tests/{appSurface.test.ts,directRunAnalytics.test.ts,directProjectTurn.test.tsx,agentRuntimeModel.test.ts,directThreadChat.test.ts}`
|
||||
(277 passed / 9 skipped)、`npm --prefix apps/ai-game-creator-shell run typecheck`、`npm run check:encoding`、
|
||||
`git diff --check`。真实客户端观感未复核。
|
||||
|
||||
## 2026-09-24 接单化 review 收口:终态写点、返修控制流、终止判据与失败投影
|
||||
|
||||
- 决策(终态的写点在整轮真正结束之后):Direct 回合先固定终态判定的上下文,`turn.completed` 的写出
|
||||
|
||||
Reference in New Issue
Block a user