文档:DirectProject 命令接单化实施计划
- 新增实施计划:四步落地顺序(Thread Manager 逻辑回合 → 命令接单 + 后台整轮 → typed 拒单 → 队列/埋点/快照/reducer),每步给改动点、不变式与验收 - 记录已落地三项(重试删除、详情引用删除、失败进池与不落历史)与三条已知坑 - docs/README.md 索引补上该计划
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# DirectProject 命令接单化实施计划
|
||||
|
||||
更新时间:`2026-09-23`
|
||||
|
||||
设计口径见 [`【ADR】DirectProject命令接单化-2026-09-23`](../adr/【ADR】DirectProject命令接单化-2026-09-23.md)。
|
||||
本文件只排实施顺序、不变式与验收,不重复设计理由。
|
||||
|
||||
## 已落地
|
||||
|
||||
- 设计定稿:ADR、`CONTEXT.md` 术语(逻辑回合 / 接单 / 拒单 / 在途回合)、两处旧文档的取代注。
|
||||
- 前端删除由 invoke 拒绝驱动的认证重试(`directCodexSessionKeepalive.ts` 只留会话保活)。
|
||||
- 用户可见文案不再带 `详情:` 引用、失败进错误上报池、失败说明不再写进项目历史、
|
||||
只服务详情展开的 IPC `read_agent_runtime_error_detail` 已删除。
|
||||
|
||||
## 第 1 步:Thread Manager 拥有逻辑回合(Rust,一个原子提交)
|
||||
|
||||
改动点:
|
||||
|
||||
- 新模块 `agent/direct_turn_accept.rs`:按 thread 维护占用登记。`accept(thread, user_item_id)` 在
|
||||
同一个临界区里完成"拒绝并发 + 登记占用 + 追加逻辑回合开始事件";`AcceptedTurn::finish(terminal)`
|
||||
幂等写出 `turn.completed` 并解除占用;`Drop` 兜底补 `host-dropped` 终态。终态写出后占用才释放。
|
||||
- `direct_thread_manager.rs`:登记与事件追加必须共用同一把锁(不要再加第二张静态表)。
|
||||
- 删除 `codex_app_server/mod.rs` 里镜像 Codex 原生回合的开始事件与终态追加,以及 app-server 侧
|
||||
武装的 `DirectTurnFailureGuard`;终态统一交给 `AcceptedTurn::finish`。
|
||||
- `direct_thread_wire.rs`:`userItemId` 的说明由"从已落盘条目读取"改成"由 `clientTurnId` 推导"。
|
||||
|
||||
不变式:线上仍只有一对生命周期事件;同一 thread 任意时刻至多一个占用;`turn.completed` 必带
|
||||
`userItemId`。
|
||||
|
||||
验收:TM 单测(并发接单被拒 / finish 幂等 / Drop 兜底 / 收口后可再次接单)+
|
||||
`cargo test agent::direct_runtime agent::direct_thread`。
|
||||
|
||||
## 第 2 步:命令改接单 + 后台跑整轮(Rust)
|
||||
|
||||
- 顺序固定为:`clientTurnId` 校验 → 占用调用身份 → 工作流恢复 → 用户条目校验 → 工程准备 →
|
||||
`accept` → 落盘用户条目 → spawn 整轮。
|
||||
- 接单前的检查从 `run_..._and_emitter` 上移到命令;分流判据改成位置(接单后一律回合失败),
|
||||
`EnvironmentNotReady` 增加 `wire_kind() = "environment-not-ready"`,"调用级拒绝直通"的分支作废。
|
||||
- spawn 出的任务在正常 / 失败 / 早退三条路径上都要走 `AcceptedTurn::finish`。
|
||||
|
||||
验收:`cargo test agent::direct_runtime`;手工把 app-server 配错,界面应收到
|
||||
`turn.completed{failed, environment-not-ready}`,而不是只有横幅。
|
||||
|
||||
## 第 3 步:拒单返回 typed 错误(Rust + TS)
|
||||
|
||||
- `DirectTurnError` 加 `Serialize + TS`(含嵌套枚举)并导出到 `chat/generated/`;命令返回
|
||||
`Result<(), DirectTurnError>`,文案仍由 `Display` 生成一次随载荷带出。
|
||||
- 前端 catch 按变体分流:认得的前置 / 参数类 → 与用户消息同级的提示、不走 `captureAgentRuntimeError`;
|
||||
认不得的 → 抛出;状态行只显示回合状态。
|
||||
|
||||
验收:`npm run ai-game-creator-shell:typecheck`;手工触发一次拒单(并发 / 空内容)确认提示位置与无上报。
|
||||
|
||||
## 第 4 步:队列、埋点、快照、reducer(TS + Rust)
|
||||
|
||||
- 前端队列放行改听"回合完成或拒单",加 TODO:以后挪到 Rust 端(落点就是接单动作)。
|
||||
- 埋点结算挂到回合终态事件。
|
||||
- 首页"运行中的项目"改由 TM 的逻辑回合导出。
|
||||
- 删除取消占位的本地收口与 `turn.started` 的重复起点兼容分支。
|
||||
|
||||
验收:typecheck;手工连发两条确认第二条不被丢;重进页面忙碌态正确。
|
||||
|
||||
## 已知坑
|
||||
|
||||
- `project.jsonl` 与项目主对话共用信封类型,不要为了"可见但不喂模型"新增行结构。
|
||||
- 埋点 `settle` 早于成绩入库会静默丢事件(未来"进历史但不喂模型"的条目同理要落在注入侧,不在读取侧)。
|
||||
- `list_game_creator_direct_active_turns` 今天读的内存表与单飞锁是同一张,搬迁时别留两处事实。
|
||||
Reference in New Issue
Block a user