diff --git a/docs/README.md b/docs/README.md index 8492cccb9..3a7649ebc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,13 +20,14 @@ ## AI 游戏创作与 Agent Runtime - [AI 游戏创作智能体 App 实施计划](./technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md):当前 DirectProject、受控语义工具、UI workflow、资源和运行时合同。 +- [策划会话 Runtime V2 接入与旧链路退役方案](./technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md):新单 Agent 策划会话、GDD 策略、未来 MCP/Skill 兼容插槽、阶段任务与退役验收合同。 - [DirectProject 客户端 Skill 与 MCP 扩展导入方案](./technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md):客户端扩展导入、按独立 Skill/MCP 拆分、命名、启用和启动时注入边界。 - [AGC 客户端更新检查与下载](./technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md):启动版本检测、OSS 清单格式和下载约定。 - [DirectProject 本轮附件路径映射](./technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md):Direct 首轮只映射附件原名与项目相对路径,不灌正文、不区别 GDD。 - [Direct 回合行为审计账本](./technical/【技术方案】Direct回合行为审计账本-2026-08-31.md):Direct GUI 回合把 native 读 / MCP / 写文件落成项目内有界时间线,用于判断有没有打开本轮附件。 - [项目开发工作台 PRD](./prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md):当前工作台页面和验收边界。 - [AGC 错误报告与诊断上传](./technical/【技术方案】AGC错误报告与诊断上传-2026-08-31.md):当前进程错误事件、应用级日志和管理员查看器合同。 -- [立项策划 Agent(Fast GDD)](<./technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md>):当前策划入口、审批和恢复合同。 +- [立项策划 Agent(Fast GDD)](<./technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md>):旧 `project-supervisor-plan` / `project-planning` 历史会话的入口、审批和恢复合同;V2 切换时未完成旧会话强制失败。 - [GameAgent 资源自由画板与快速编辑](./technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md) - [UI 工作流资源桥接与 Runtime 执行](./【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md) - [UI 编辑器 Godot 容器布局](./technical/【技术方案】UI编辑器Godot容器布局模型-2026-08-18.md) diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index a2eb686c4..6a798c8c6 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -15,6 +15,16 @@ - 关联文档:相关 PRD、技术文档、提交或 Issue ``` +## 2026-09-03 新建策划会话采用 PlanningSessionRuntime V2,旧 Supervisor 链路直接退役 + +- 背景:现有“做方案”依赖 `project-supervisor-plan` 根 Run、`project-planning` 子 Run、静态委派、delivery、Acceptance Graph 和审批前 evidence。新策划 Agent 只需要单 Agent 会话、问询、GDD 和审批;继续在旧 Runtime 上逐条放宽会保留身份/编排耦合。未来策划 Agent 可能支持无限多轮、MCP 和 Skill,需要避免把当前 8 题/GDD/no-tools 固化为 Runtime 根结构。 +- 决策:新增独立 `PlanningSessionRuntime`,复用 Provider/流式、会话持久化、项目锁、原子写和基础错误恢复;当前启用 `mode=gdd`、最多展示 8 个有效问题、GDD 审批和用户修改。新建“做方案”会话不创建 Supervisor root、planning child、delegation 或 acceptance evidence。V2 使用独立 `.agent/planning-v2/` 与 V2 schema,继续输出 `game/fast_gdd.md`;不自动转换旧会话。 +- 兼容性:Session 保存 `mode`、可空 `questionLimit`、`capabilities.tools/skills`;完整会话记录与 Provider 请求上下文分离;消息模型预留 tool/skill 事件类型但本期不执行 MCP/Skill。无限问询、上下文摘要、多产物和能力执行以后作为策略/能力层扩展,不重新引入 Supervisor 身份模型。 +- 退役:V2 切换时旧链路直接封存;所有未完成旧会话投影为 `legacy_retired` 失败,禁止继续问询、审批、恢复或 continuation。旧 GDD、approval、conversation 和 `.agent/planning` 文件只读保留;旧入口 caller 关闭,但不删除旧代码、旧测试或旧数据。 +- 影响范围:AGC 做方案入口、Rust/Tauri planning session/Provider adapter、GDD/审批 V2、前端 planning lane、阶段任务与 BDD 验收;做游戏/做素材 DirectProject 不变。 +- 验证方式:按 `docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md` 的 P0~P5 阶段验收执行;至少覆盖第 8 个问题、上限后 question 抑制、Provider 失败、非法输出、批准/修改/退回、重启恢复、旧会话切换强制失败、迟到 Provider 结果丢弃和当前空能力快照。 +- 关联文档:`docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`、`docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`。 + ## 2026-09-02 GDD 审批卡的后台 hydrate 不抢占已加载决定 - 背景:项目页首次加载和运行态刷新可能并发 hydrate。卡片已经显示后,短暂的 `hydrateBusy` 会让已打开的评论弹层提交按钮瞬时变灰,用户无法提交已输入的修改意见。 diff --git a/docs/project-memory/shared-memory/document-map.md b/docs/project-memory/shared-memory/document-map.md index 9d754cb5d..fcaa3b0ff 100644 --- a/docs/project-memory/shared-memory/document-map.md +++ b/docs/project-memory/shared-memory/document-map.md @@ -22,14 +22,15 @@ AI 游戏创作 / DirectProject / UI workflow: 1. `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` -2. `docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md` -3. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` -4. `docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md` -5. `docs/technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md` -6. `docs/technical/【技术方案】Direct回合行为审计账本-2026-08-31.md` -7. `docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md` -8. `docs/【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md` -9. UI 编辑器、宿主壳和当前测试专题文档 +2. `docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md` +3. `docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md` +4. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` +5. `docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`(仅存量旧链路) +6. `docs/technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md` +7. `docs/technical/【技术方案】Direct回合行为审计账本-2026-08-31.md` +8. `docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md` +9. `docs/【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md` +10. UI 编辑器、宿主壳和当前测试专题文档 图片画布 / 媒体生成: diff --git a/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md b/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md new file mode 100644 index 000000000..f449003e2 --- /dev/null +++ b/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md @@ -0,0 +1,756 @@ +# 策划会话 Runtime V2 接入与旧链路退役方案 + +- 日期:2026-09-03 +- 状态:待开工,本文是新生产实现的目标方案与阶段验收合同 +- 适用范围:AGC 桌面 App 的“做方案”入口、策划会话、GDD 产物与审批 + +> 本文只规定新策划 Agent 的生产接入和旧链路退役方式,不修改当前生产代码。现有 `project-supervisor-plan` / `project-planning` 链路在 V2 切换前仍是存量实现;V2 切换时旧链路直接封存,所有未完成旧会话强制失败,旧 Fast GDD 文档之后只作为历史记录依据。 + +## 1. 决策摘要 + +本次不在旧 Supervisor Runtime 上逐条删除门禁,而是新增一个单 Agent 的 `PlanningSessionRuntime`(下称 Runtime V2): + +```text +做方案 + → PlanningSessionRuntime + → 一个策划 Agent Session + → Provider(流式) + → question 或 GDD + → 用户回答 / 审批 + → 同一 Session 继续 +``` + +V2 复用底层能力,但不复用旧策划编排身份: + +- 复用 Provider 连接、流式响应、超时/瞬态重试、会话消息持久化、项目路径边界、单项目并发控制和原子文件写入。 +- 不经过 Project Supervisor,不创建 `project-planning` 子 Run,不使用 `agent.delegate`、delivery、continuation、Acceptance Graph 或 acceptance evidence。 +- 当前只启用 `mode=gdd`、最多展示 8 个有效问题、GDD 审批和用户修改。 +- 当前不启用 MCP、Skill、工具调用或无限问询,但会在会话、消息、上下文和能力快照中预留兼容插槽。 +- 新旧会话分开持久化,不自动转换旧会话;切换时所有未完成旧会话强制失败;同一项目同一时间只允许一条策划权威会话推进。 + +### 1.1 本次必须达到的结果 + +1. 新的“做方案”入口不再创建 `project-supervisor-plan` 根 Run。 +2. 单个策划 Agent 能在同一会话中完成提问、回答、GDD 生成、审批、修改和退回。 +3. `PLAN_MAX_TURNS=8` 表示最多向用户展示 8 个有效问题;第 8 个问题允许展示,达到 8 后再次返回 question 不得展示,内部最多重试一次要求直接出 GDD。 +4. GDD、非法输出、Provider 请求失败和用户修改不增加有效问题数。 +5. Provider 失败、进程重启或页面重新打开后,不重复已完成的 Provider 副作用,不丢失已经持久化的用户消息和 GDD 版本。 +6. V2 切换时旧链路直接退役;所有未完成旧会话进入明确的 `legacy_retired` 失败状态,旧产物仍可读取。 + +### 1.2 明确不做 + +- 本次不实现无限多轮产品能力;只保证会话计数和上下文接口不把未来轮次锁死。 +- 本次不接入 MCP、Skill、第三方工具、工具审批或工具恢复。 +- 本次不实现上下文自动摘要、向量检索或无限历史存储;只分离完整会话记录与 Provider 请求上下文。 +- 本次不绑定批准 GDD 与后续做游戏的 `approvedGddRef`。 +- 本次不改做游戏/做素材的 DirectProject 路由。 +- 本次不删除旧 Runtime 源码、旧测试或旧 `.agent/planning` 产物。 +- 本次不保证未完成旧会话继续运行、继续问询或继续审批;切换后它们只能查看历史记录。 +- 本次不把 V2 做成 Python 子进程;生产实现仍在 AGC 客户端 Rust/Tauri 侧。 + +## 2. 当前生产链路与迁移原因 + +当前“做方案”生产路径是旧 Supervisor 链路: + +```text +planningStartMode + → project-supervisor-plan 根 Run + → agent.delegate + → project-planning 子 Run + → planning_coordinator + → plan.submit_gdd + → acceptance evidence / claim + → GDD approval pending +``` + +现役入口和身份绑定主要分布在: + +- `apps/ai-game-creator-shell/src/App.tsx` +- `apps/ai-game-creator-shell/src/features/agent-runtime/model.ts` +- `apps/ai-game-creator-shell/src-tauri/src/commands.rs` +- `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs` +- `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/planning_coordinator.rs` +- `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/planning_submit.rs` +- `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/planning_approval.rs` + +旧链路的复杂度不是单一校验,而是多组相互依赖的身份与编排事实: + +- Supervisor 根 Run、`project-planning` 子 Run、父子 Run Profile; +- `agent.delegate`、delivery、continuation lineage 和 claim journal; +- `plan.submit_gdd` 的 child 身份限制; +- GDD 审批前的 Acceptance Graph / acceptance evidence; +- `project-supervisor-plan` source 与 active root 判定; +- 前端运行态、子 Agent 状态和审批 pending 的联动。 + +如果在旧 Runtime 内逐个放宽这些限制,容易出现“提示词已经单 Agent、执行层仍要求 Supervisor/child 身份”的半迁移状态,典型结果是身份不匹配、错误恢复或 `needs-reconciliation`。因此 V2 以新会话运行内核接入;旧链路不再作为可推进的运行时,只在切换时被封存并保留历史文件。 + +## 3. V2 目标架构 + +### 3.1 分层 + +```text +┌──────────────────────────────────────────┐ +│ PlanningSessionRuntime │ +│ - 会话状态 / 回合生命周期 │ +│ - 单 Agent 调用 │ +│ - question / artifact 结果分流 │ +│ - 恢复、计时、失败投影 │ +└──────────────────────────────────────────┘ + │ +┌──────────────────────────────────────────┐ +│ PlanningPolicy │ +│ 当前:GddPlanningPolicy │ +│ - 有效问题计数 │ +│ - question 上限 │ +│ - GDD 结构与版本 │ +│ - 审批 / 修改 / 退回 │ +└──────────────────────────────────────────┘ + │ +┌──────────────────────────────────────────┐ +│ Shared Provider / Session substrate │ +│ - provider-neutral request/stream │ +│ - 会话消息落盘 │ +│ - 项目锁、原子写、超时、基础重试 │ +│ - 上下文构建接口 │ +└──────────────────────────────────────────┘ +``` + +Runtime V2 不负责解释 GDD 字段;`GddPlanningPolicy` 也不负责 Provider 连接、文件锁或未来 MCP 进程。 + +### 3.2 当前与未来能力的边界 + +当前配置快照: + +```json +{ + "mode": "gdd", + "questionLimit": 8, + "capabilities": { + "tools": [], + "skills": [] + } +} +``` + +未来可以在不改会话核心的情况下扩展为: + +```json +{ + "mode": "conversation", + "questionLimit": null, + "capabilities": { + "tools": ["mcp.example.search"], + "skills": ["planning-research.v1"] + } +} +``` + +`questionLimit`、`mode` 和 `capabilities` 是策略/能力快照,不是 Runtime 的硬编码身份。当前空能力集合不意味着未来消息格式只能承载普通文本。 + +### 3.3 一次回合的统一结果 + +Provider 回合在 Runtime 内统一归一为以下结果之一: + +```text +Question(question) +Artifact(artifact) +ToolCall(toolCall) # 当前不启用,仅保留消息/事件类型 +AssistantText(text) # 当前策略只允许作为非法输出处理;未来可由 conversation 模式使用 +``` + +当前 `GddPlanningPolicy` 只接受 `Question` 或 `Artifact(kind=gdd)`。其它结果不写成成功产物;按输出重试策略处理,超过重试上限后进入可恢复失败状态。 + +## 4. 会话与状态合同 + +### 4.1 V2 会话快照 + +建议持久化为 `planning-session.v2`: + +```json +{ + "schemaVersion": "planning-session.v2", + "engine": "planning-session-v2", + "mode": "gdd", + "status": "awaiting_approval", + "turnIndex": 3, + "questionCount": 2, + "questionLimit": 8, + "revisionCount": 0, + "currentArtifactVersion": 1, + "currentQuestion": null, + "capabilities": { + "tools": [], + "skills": [] + }, + "processingSeconds": 123.45 +} +``` + +约束: + +- `turnIndex` 是会话回合序号,不限制为 8 或 3;未来无限对话仍可继续递增。 +- `questionCount` 只统计已经展示给用户的有效 question。 +- `questionLimit` 由策略读取;当前值为 8,未来无限模式可为 `null`。 +- `revisionCount` 统计用户对当前产物发起的修改次数,不并入 questionCount。 +- `capabilities` 记录本会话可用能力快照;当前必须为空数组。 + +### 4.2 状态 + +```text +idle + → planning + → awaiting_user + → planning + → awaiting_approval + → approved + +awaiting_approval + → revision_requested + → planning + +awaiting_approval + → rejected + +planning + → provider_failed / stopped +``` + +`provider_failed` 是可恢复的失败投影,不代表 GDD 被拒绝;重试时必须沿用当前 Session 和未完成的用户意图。`needs-reconciliation` 不作为 V2 的正常业务状态;只有发生不可判断的持久化冲突时,才进入单独的恢复错误并阻止自动覆盖。 + +### 4.3 问题上限语义 + +`PLAN_MAX_TURNS=8` 的准确语义:最多向用户展示 8 个有效问题,而不是最多调用 Provider 8 次。 + +```text +questionCount=7,本次返回 question +→ 保存并展示 +→ questionCount=8 + +questionCount=8,本次返回 GDD +→ 正常接受,不增加 questionCount + +questionCount=8,本次返回 question +→ 不保存、不展示、不进入 awaiting_user +→ 追加内部提示“不能再提问,直接根据已有信息出 GDD” +→ 最多重试 1 次 +``` + +其它规则: + +- 非法 JSON/GDD 不增加 `questionCount`。 +- Provider 请求失败不增加 `questionCount`,也不创建 GDD 版本。 +- 用户修改不受 `questionLimit` 限制,但修改回合仍不能再次向用户展示 question;若 Provider 返回 question,按一次内部出稿重试处理。 +- 达到内部输出重试上限后,保留当前会话和错误摘要,允许用户再次提交或恢复,不伪造 GDD。 + +## 5. Provider、上下文与未来 MCP/Skill 兼容性 + +### 5.1 Provider 适配边界 + +`GddPlanningPolicy` 不直接构造 OpenAI/Anthropic 请求体。Runtime 只调用 provider-neutral 接口: + +```text +build_request(context, capability_snapshot, policy_hint) +start_stream(request) +collect_stream_events() +normalize_turn_result() +``` + +当前实际 Provider 配置、Responses 流式格式、超时、瞬态重试和凭据边界沿用 AGC 现有 Provider substrate;V2 不改变当前 Provider 路由,也不引入新的第三方模型协议。 + +### 5.2 完整会话与请求上下文分离 + +```text +conversation.jsonl(完整事实记录) + │ + ▼ +ContextBuilder(本次请求上下文) + │ + ├─ 当前策略提示 + ├─ 关键决定/当前产物 + ├─ 最近消息窗口 + └─ 未来摘要/工具结果/Skill 引用 +``` + +当前实现可以先按有界完整历史构建请求,但必须通过 `ContextBuilder` 接口进入 Provider,不能把磁盘 JSONL 直接当作永久请求格式。当前不实现摘要;如果配置的上下文预算不足,应返回明确的上下文超限错误,不静默丢弃历史。未来再增加摘要或分页时,不改变持久化消息事实。 + +### 5.3 MCP / Skill 预留而不提前执行 + +当前只做数据边界: + +- Session 保存 `capabilities.tools` 与 `capabilities.skills` 的快照,当前为空。 +- 消息模型预留 `tool_call`、`tool_result`、`skill_reference` 类型,当前不产生。 +- Provider 请求接受能力快照参数,当前不向模型广告工具。 +- 能力启用由客户端/宿主决定,模型不能自行开启 MCP 或加载 Skill。 + +当前不做 MCP 进程管理、Skill 安装、工具权限、工具审批、外部副作用账本或工具恢复。 + +## 6. 持久化与新旧并存 + +### 6.1 V2 目录 + +V2 使用独立目录,避免被旧 `planning_storage.rs` 的 Supervisor 身份校验读取: + +```text +.agent/planning-v2/ +├─ session.json +├─ conversation.jsonl +├─ index.json +├─ gdd.v1.json +├─ gdd.v2.json +└─ approvals/ + ├─ v1.json + └─ v2.json +``` + +继续生成同一用户可见路径: + +```text +game/fast_gdd.md +``` + +该路径是当前 UI 和后续“做成游戏”入口的稳定交付面;V2 写入时必须使用项目写锁、临时文件和原子替换。 + +### 6.2 V2 GDD 与审批 + +V2 GDD 建议使用 `plan-gdd.v2`,只保存业务内容和 V2 自身身份: + +```json +{ + "schemaVersion": "plan-gdd.v2", + "version": 1, + "createdAtUtc": "...", + "game": {}, + "decisions": [], + "prototypeValidationItems": [], + "fingerprint": "..." +} +``` + +不写入旧链路字段: + +```text +rootAgentId +rootRunId +delegationId +runProfile +runProfileBindingFingerprint +sourceSessionRevision +createdByRunId +``` + +审批记录绑定 `version + fingerprint`: + +```json +{ + "schemaVersion": "plan-approval.v2", + "version": 1, + "gddFingerprint": "...", + "action": "approve", + "comment": "", + "atUtc": "..." +} +``` + +### 6.3 新旧会话路由 + +同一项目只允许一个活跃策划权威。V2 切换包含一次项目级“旧链路封存”操作,路由规则如下: + +| 项目状态 | 新请求路由 | +|---|---| +| 已有活跃 V2 会话 | 继续 V2;同一会话只允许一个在途 Provider 回合 | +| 只有旧 `project-supervisor-plan` 活跃会话 | 切换时将旧会话投影为 `legacy_retired` 失败;用户需重新创建 V2,不再继续旧链路 | +| 没有活跃策划会话 | 创建 V2 | +| 旧会话已终态、用户明确重新做方案 | 创建 V2,不改写旧目录 | +| 同时发现旧/V2 活跃会话 | 旧会话优先封存为 `legacy_retired`,只保留 V2 推进 | + +不做旧 session → V2 的自动转换。原因是两套身份、计数、审批和 GDD schema 不同,自动转换会把旧 pending 或旧 approval receipt 混入 V2。 + +### 6.4 旧链路一次性封存 + +切换由客户端在项目写锁内执行一次: + +1. 读取旧 `.agent/planning/session.json` 的当前阶段;`collecting`、`awaiting_user_input`、`awaiting_gdd_approval`、`revision_requested` 和 `recovery_required` 均视为未完成。 +2. 不改写旧 `plan-session.v1` 的字段形状;在 `.agent/planning-v2/legacy-cutover.json` 写入旧 session 指纹、原阶段、切换时间和 `state=legacy_retired`。 +3. V2/前端 hydrate 看到该标记后,把旧会话显示为“旧策划链路已退役(失败)”,禁止继续问询、审批、恢复或创建旧 continuation。 +4. 已经在途的旧 Provider 结果只允许落诊断,不得写入新的旧 GDD、approval receipt 或 `game/fast_gdd.md`;切换后的新写入只由 V2 负责。 +5. 旧 `gdd.v*.json`、旧 `index.json`、旧 approval receipt 和旧 conversation 仍保留只读,不删除、不改写、不迁移。 + +旧 session 缺失或损坏时,也不尝试修复后继续;写入 `legacy_retired` 封存标记并阻止旧入口,避免把不可判断的旧状态带入 V2。 + +## 7. 前端与命令接入 + +### 7.1 入口分流 + +目标分流: + +```text +做方案 → PlanningSessionRuntime V2 +做游戏 → DirectProject +做素材 → DirectProject +``` + +`planningStartMode` 仍可作为首页到工作台的入口标记,但它不再映射到 `project-supervisor-plan`。首轮提交、后续回答、审批意见和恢复都调用 V2 命令。 + +### 7.2 V2 命令边界 + +建议新增独立命令(名称可在 P0 冻结): + +```text +start_planning_session_v2 +resume_planning_session_v2 +submit_planning_user_input_v2 +decide_planning_artifact_v2 +hydrate_planning_session_v2 +``` + +命令只接收项目路径、Session 标识、用户文本/选项和 V2 产物身份;不接收或生成 Supervisor 根 Run、delegation、acceptance evidence 等字段。 + +### 7.3 UI 复用边界 + +第一版可复用现有: + +- `ProjectSupervisorView` 的聊天区域和工作台布局; +- `GddApprovalCard` 的产物展示与审批交互; +- 现有耗时展示和会话历史加载。 + +但数据来源必须改为 V2 状态,不再把“页面组件叫 Supervisor”当作运行时身份。后续再把组件重命名为 `PlanningSessionView`,不作为本次切换前置。 + +## 8. 最小安全与业务校验 + +### 8.1 保留 + +- 项目路径必须属于当前用户打开的项目。 +- 单项目单活跃策划回合;重复提交同一 client turn 必须幂等。 +- Provider 超时、瞬态失败和稳定错误摘要。 +- 输出 JSON 可解析;当前 GDD 必填业务字段、长度和基本类型合法。 +- GDD 版本严格递增,文件写入原子化。 +- 审批必须绑定当前最新 GDD 的版本和 fingerprint。 +- 旧审批不能覆盖新 GDD;Provider 失败不能伪造成成功。 +- 重启后可以恢复当前 Session,不重复已经提交成功的消息/产物。 + +### 8.2 不迁移 + +- Supervisor 根/子 Run 身份和 parent binding fingerprint。 +- `agent.delegate`、delivery、continuation、claim journal。 +- Acceptance Graph、acceptance evidence、Supervisor claim gate。 +- `project-supervisor-plan` source。 +- 固定 A/B/“需要原型验证”三选一硬协议。 +- `answerSource` 作为阻断条件。 +- 3 轮硬限制。 + +未来 MCP/Skill 的工具权限校验属于能力执行层,不重新引入上述 Supervisor 身份模型。 + +## 9. 阶段任务拆分 + +阶段按“先冻结合同,再做内核,再切入口,最后退役”执行。每个阶段完成后才进入下一阶段;阶段之间不要求一次性重写旧链路。 + +### P0:V2 合同冻结(文档与接口设计) + +目标:把 V2 与旧链路的边界写成开发可执行合同。 + +任务: + +| ID | 任务 | 产出 | +|---|---|---| +| P0-1 | 冻结 Session、消息、回合结果、产物和审批 DTO | V2 schema 草案、字段枚举和版本策略 | +| P0-2 | 冻结状态机、`questionLimit` 语义和重试规则 | 状态转移表、错误边界 | +| P0-3 | 冻结新旧并存与同项目单权威规则 | 路由/恢复决策表 | +| P0-4 | 冻结 Provider/ContextBuilder/Capability 插槽 | Rust trait/模块边界草案 | + +阶段验收: + +- 产品、前端、Runtime 对“第 8 个问题”和“第 9 次 question”能按同一例子解释。 +- 文档中不再出现“V2 先复用旧 Supervisor 再逐项放宽”的实现路径。 +- 能明确区分完整会话记录、Provider 请求上下文、GDD 产物和审批记录。 +- 明确旧会话如何封存、何时创建 V2,以及如何拒绝旧/V2 双活。 + +依赖:无。完成后才能开始 P1。 + +### P1:PlanningSessionRuntime 内核 + +目标:在不包含 GDD 业务规则的情况下,跑通单 Agent 会话、流式响应、持久化和恢复。 + +任务: + +| ID | 任务 | 产出 | +|---|---|---| +| P1-1 | 新建 V2 Session 生命周期与单项目并发控制 | `planning_session_v2` Rust 模块 | +| P1-2 | 接入现有 Provider substrate 和流式事件归一 | provider-neutral request/stream adapter | +| P1-3 | 实现消息 JSONL、回合身份和幂等写入 | `conversation.jsonl` 及 turn identity | +| P1-4 | 实现 ContextBuilder 初版 | 有界历史构建;超限显式失败 | +| P1-5 | 实现 Provider 失败/中断/重启恢复 | Session 不丢消息、不伪造成功 | +| P1-6 | 记录 `turnIndex`、处理耗时和安全错误摘要 | Session 快照、诊断字段 | + +阶段验收: + +- 真实 Provider 可以返回一轮流式文本,前端收到增量并在终态落盘。 +- 同一 `clientTurnId` 重试不会重复追加用户/助手消息。 +- 同一项目第二个在途回合被拒绝,原回合不受影响。 +- Provider 失败后 Session 保留,恢复不会自动制造新问题或 GDD。 +- 重启后能读取完整会话记录;请求上下文不依赖前端临时内存。 +- P1 不包含 `agent.delegate`、Supervisor root、GDD 校验或审批逻辑。 + +依赖:P0。 + +### P2:GddPlanningPolicy 与 V2 产物闭环 + +目标:把新版原型的策划行为落到生产 V2,不把旧 Supervisor 协议带回来。 + +任务: + +| ID | 任务 | 产出 | +|---|---|---| +| P2-1 | 实现 question / GDD 结果解析 | 只接受当前策略需要的结果 | +| P2-2 | 实现最多 8 个有效问题的策略计数 | `questionCount` 与 `turnIndex` 分离 | +| P2-3 | 实现达到上限后的单次强制出稿重试 | 不保存/展示额外 question | +| P2-4 | 实现 V2 GDD schema、版本链和 `fast_gdd.md` | `.agent/planning-v2/**` 与 Markdown | +| P2-5 | 实现审批、修改、退回 | `plan-approval.v2` 与新版本生成 | +| P2-6 | 实现轻量输入归一化 | A/B/编号/完整 label/“按第一个选项做”映射 | + +阶段验收: + +- 0 轮直出 GDD 可保存并进入审批。 +- 第 8 个有效问题可展示;第 8 个问题后模型再次返回 question 时,用户看不到该问题,内部最多重试一次并要求出 GDD。 +- 非法 JSON/GDD、Provider 失败不增加 `questionCount`。 +- 审批“批准”产生 approved 状态;“修改”产生新 GDD 版本且旧版本只读;“退回”不伪造批准。 +- `answerSource` 即使缺失或使用等价值,也不会成为唯一阻断原因;结构和业务字段仍需合法。 +- V2 GDD 不包含旧 Supervisor 身份字段。 +- 不出现固定三选一或 `project-planning` child 合同。 + +依赖:P1。 + +### P3:生产入口与 UI 接入 + +目标:让用户从正式“做方案”入口使用 V2,同时保持现有页面可用。 + +任务: + +| ID | 任务 | 产出 | +|---|---|---| +| P3-1 | 新增 V2 Tauri command 注册和前端 invoke 封装 | 命令可启动/恢复/审批 | +| P3-2 | 将 `planningStartMode` 路由到 V2 | 新项目不创建旧 Supervisor root | +| P3-3 | 复用审批卡并切换到 V2 hydrate 状态 | GDD 展示、版本和审批按钮正常 | +| P3-4 | 加入当前运行态、流式回复和耗时展示 | 页面可见状态与 Session 一致 | +| P3-5 | 识别旧项目并准备封存投影 | 存量旧会话不被误路由到 V2 | + +阶段验收: + +- 新项目点击“做方案”后,持久化目录是 `.agent/planning-v2/`,不产生新的 `project-supervisor-plan` 或 `project-planning` Run。 +- 前端能展示 question、接收用户答案、展示 GDD 并完成审批。 +- 刷新页面/重启 App 后可以恢复 V2 当前等待态。 +- 做游戏、做素材入口行为与改造前一致。 +- 旧活跃策划项目不会与 V2 双活;切换封存后显示明确失败并要求重新创建 V2。 + +依赖:P2。 + +### P4:灰度、真实 Provider 与回归验收 + +目标:证明 V2 的正常路径和关键失败路径可用,再关闭旧入口新建能力。 + +任务: + +| ID | 任务 | 产出 | +|---|---|---| +| P4-1 | 离线状态/结构定向测试 | Session、策略、schema、审批测试 | +| P4-2 | 真实 Provider 测试 | 流式、问题、GDD、失败恢复 | +| P4-3 | 前端组件/工作台测试 | 路由、审批卡、恢复显示 | +| P4-4 | 旧链路切换封存测试 | 未完成旧 session 强制失败、V2 不误读旧目录 | +| P4-5 | 安全与编码门禁 | `npm run check:encoding`、`git diff --check` 及相关 Rust/TS 检查 | + +阶段验收: + +- 真实 Provider 至少完成“提问 → 回答 → GDD → 批准”和“GDD → 修改 → 新版本 → 批准”两条链路。 +- 至少覆盖一次 Provider 请求失败、一次非法输出和一次重启恢复。 +- 证实旧目录中的 delivery/approval 不会被 V2 hydrate 或审批读取。 +- 证实同一项目不存在两个活跃策划权威;旧活跃会话在切换后不可继续。 +- 所有失败均保留可操作状态,不以成功文案掩盖 Provider/持久化错误。 + +依赖:P3。 + +### P5:旧链路退役 + +目标:停止新业务进入旧 Supervisor,并将所有未完成旧会话一次性封存为失败。 + +任务: + +| ID | 任务 | 产出 | +|---|---|---| +| P5-1 | 关闭新建和继续旧 `project-supervisor-plan` 的 caller | 入口门禁/路由变更 | +| P5-2 | 执行旧 session 一次性封存 | `legacy-cutover.json` 与失败投影 | +| P5-3 | 保留旧产物只读展示,禁止旧交互继续推进 | 历史查看能力 | +| P5-4 | 更新生产文档和运维说明 | 旧链路退役状态、回滚边界 | + +阶段验收: + +- 代码搜索和运行时审计均证明新“做方案”不再调用 `start_game_creator_supervisor_runtime_task`。 +- 新项目不会创建旧 Supervisor root、child Run、delivery 或 acceptance evidence。 +- 已存在的旧活跃会话全部投影为 `legacy_retired` 失败;已终态旧产物仍可查看。 +- 旧入口或旧 continuation 若被直接调用,返回稳定的“旧链路已退役”错误,不删除旧数据。 +- 切换前已在途的旧 Provider 迟到结果不会写入 GDD、审批或 `game/fast_gdd.md`。 +- 做游戏 DirectProject 和其它现役 Agent Runtime 不受影响。 + +依赖:P4 通过;确认切换窗口并完成一次性封存。 + +## 10. BDD 验收场景 + +### 功能:新项目走单 Agent 策划会话 + +为了去掉不必要的 Supervisor 编排,作为创作者,我希望“做方案”直接进入一个策划会话。 + +```gherkin +场景: 新项目首次进入做方案 + 假如项目没有活跃的旧策划会话,也没有 V2 会话 + 当用户从首页进入“做方案”并提交初始需求 + 那么系统应创建一个 planning-session-v2 会话 + 而且该会话只有一个策划 Agent + 而且不应创建 project-supervisor-plan 根 Run、project-planning 子 Run 或 agent.delegate delivery +``` + +### 功能:问询与问题上限 + +```gherkin +场景: 第 8 个问题仍然可以展示 + 假如 V2 会话已经展示 7 个有效问题 + 当 Provider 返回第 8 个合法 question + 那么系统应保存并展示该问题 + 而且 questionCount 应为 8 + 而且 turnIndex 应按实际 Provider 回合递增 + +场景: 达到问题上限后不再向用户展示问题 + 假如 V2 会话的 questionCount 已为 8 + 当 Provider 返回合法 question + 那么系统不应保存或展示该 question + 而且不应进入 awaiting_user + 而且系统应追加内部出稿提示并最多重试一次 + 而且重试得到合法 GDD 时应进入 awaiting_approval + +场景: 达到问题上限时直接返回 GDD + 假如 V2 会话的 questionCount 已为 8 + 当 Provider 直接返回合法 GDD + 那么系统应正常保存 GDD + 而且不应追加额外 question +``` + +### 功能:Provider 与非法输出失败边界 + +```gherkin +场景: Provider 请求失败后恢复 + 假如 V2 会话正在 planning 且尚未得到本次结果 + 当 Provider 请求超时或返回瞬态失败 + 那么系统应保留当前 Session 和已落盘消息 + 而且不应增加 questionCount + 而且不应创建新的 GDD 版本 + 而且用户可以重试或恢复同一会话 + +场景: 非法 GDD 不被伪装成成功 + 假如 Provider 返回无法解析或缺少必填字段的 GDD + 当输出校验完成 + 那么系统应按当前重试上限请求修正 + 而且重试耗尽后应显示可操作失败 + 而且不得写入 approved GDD +``` + +### 功能:审批、修改与退回 + +```gherkin +场景: 用户批准当前 GDD + 假如当前存在 V2 最新 GDD 且审批卡引用的 fingerprint 与文件一致 + 当用户选择批准 + 那么系统应写入 V2 approval receipt + 而且会话状态应为 approved + 而且旧 GDD 文件保持可读 + +场景: 用户修改当前 GDD + 假如当前 GDD 正在等待审批 + 当用户提交修改意见 + 那么系统应以当前 GDD 为基线启动同一 V2 Session 的修订回合 + 而且用户修改不应消耗 questionLimit + 而且成功后应生成递增版本的新 GDD + 而且旧版本不应被覆盖 + +场景: 过期审批不能覆盖新版本 + 假如审批卡引用 v1,但当前最新 GDD 已经是 v2 + 当用户提交 v1 的批准或修改 + 那么系统应拒绝该决定 + 而且 v2 内容和状态不得改变 +``` + +### 功能:恢复与新旧并存 + +```gherkin +场景: App 重启后恢复等待用户回答 + 假如 V2 会话已持久化一个合法 question 且状态为 awaiting_user + 当 App 重启并重新打开项目 + 那么系统应恢复同一 question + 而且不应再次调用 Provider 生成新 question + +场景: 旧活跃会话在切换时强制失败 + 假如项目已有活跃的 project-supervisor-plan 会话 + 当系统切换到 PlanningSessionRuntime V2 + 那么旧会话应被投影为 legacy_retired 失败 + 而且不得再接受旧问询、审批、恢复或 continuation + 而且用户重新做方案时只能创建 V2 会话 + +场景: 旧 Provider 迟到结果不能复活旧链路 + 假如旧会话在切换时已有一个 Provider 请求在途 + 当该请求在切换后返回 GDD 或 question + 那么系统不得写入旧 GDD、approval receipt 或 game/fast_gdd.md + 而且旧会话仍保持 legacy_retired 失败 + +场景: V2 不读取旧 planning 目录 + 假如项目同时存在旧 .agent/planning 和 V2 .agent/planning-v2 目录 + 当系统 hydrate V2 会话 + 那么系统只能读取 V2 schema 和产物 + 而且旧 delivery、旧 approval receipt 和旧 Run 身份不得改变 V2 状态 +``` + +### 功能:未来能力插槽的当前行为 + +```gherkin +场景: 当前 V2 会话不启用 MCP 或 Skill + 假如用户创建新的 V2 策划会话 + 当 Runtime 构建 Provider 请求 + 那么能力快照中的 tools 和 skills 应为空数组 + 而且 Provider 请求不应广告 MCP/Skill 工具 + 而且会话 schema 应能保存该空能力快照 +``` + +## 11. 测试映射 + +| 场景/规则 | 测试层级 | 计划目标 | +|---|---|---| +| Session 状态、questionCount/turnIndex 分离 | Rust unit | `planning_session_v2` | +| Provider 失败、幂等回合、恢复 | Rust integration | V2 runtime/provider adapter tests | +| GDD schema、版本链、fingerprint | Rust unit/integration | V2 artifact/approval tests | +| 第 8 个问题与上限后重试 | Rust unit | `GddPlanningPolicy` tests | +| 审批批准/修改/退回/过期审批 | Rust integration | V2 approval tests | +| 输入“按 A 做/按第一个选项做” | Rust/TS unit | input normalization tests | +| 做方案入口路由 | frontend integration | `App`/planning lane tests | +| 问题卡、GDD 卡和恢复态展示 | component | `ProjectSupervisorView`/`GddApprovalCard` tests | +| 真实 Provider 流式链路 | real provider smoke | P4 独立脚本或现有 real-e2e harness | +| 旧会话切换强制失败、旧目录不被 V2 读取 | Rust integration | legacy cutover/recovery tests | +| 中文编码和文档 diff | repository gate | `npm run check:encoding`、`git diff --check` | + +未接入 Cucumber/Playwright runner 前,以上 BDD 先作为 Markdown 验收合同;不为本方案新增独立 BDD 测试框架。 + +## 12. 风险与处理原则 + +| 风险 | 处理 | +|---|---| +| 继续复用旧 `planning_submit.rs` 导致 Supervisor 身份回流 | V2 使用独立 artifact/approval 模块;只复用通用文件/锁能力 | +| 新旧都写 `game/fast_gdd.md` | 同一项目单活跃策划权威;V2/旧路径均使用项目锁和原子写 | +| 无限会话导致上下文无限膨胀 | 当前先分离完整记录和 ContextBuilder;超预算显式失败,后续再加摘要 | +| 未来 MCP/Skill 侵入 GDD 策略 | 能力快照和消息类型在 Runtime 层预留,当前策略不广告、不执行 | +| 强制失败导致旧 pending/receipt 不再可继续 | 这是本次明确的退役语义;旧文件只读保留,不迁移、不删除 | +| 前端组件名继续叫 Supervisor 造成误解 | 第一阶段只切数据源;后续独立重命名,不把命名重构当接入前置 | + +## 13. 完成定义 + +本方案对应的工程工作只有在以下条件全部满足后才可宣布完成: + +- P0~P4 阶段验收通过,真实 Provider 至少跑通一条审批链和一条修改链。 +- 新“做方案”入口的运行时审计中不再出现新的 Supervisor root/child/delivery。 +- V2 Session、GDD 和审批记录可在重启后恢复,且旧目录不会污染 V2。 +- P5 关闭旧新建/继续入口;所有未完成旧会话均为 `legacy_retired` 失败,历史产物仍可只读查看。 +- 做游戏/做素材 DirectProject 路径无回归。 +- 相关 Rust/TS 定向验证、`npm run check:encoding` 和 `git diff --check` 通过。