冻结策划会话 Runtime V2 P0 合同
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled

固定 Session、消息、回合结果、GDD 产物和审批记录的 V2 schema。

固定四个 V2 command、输入归一化和 questionLimit=8 语义。

固定 Provider adapter、ContextBuilder、能力快照及未来 MCP/Skill 扩展边界。

固定旧 Supervisor 链路 legacy-cutover 封存和未完成会话强制失败规则。

标记 P0 完成并同步项目决策记录。
This commit is contained in:
2026-09-03 07:25:19 +00:00
parent 044c8cfadf
commit e38edfb446
2 changed files with 163 additions and 14 deletions
@@ -20,6 +20,7 @@
- 背景:现有“做方案”依赖 `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 身份模型。
- 当前进度:P0 合同冻结已完成,已固定 `planning-session.v2``planning-message.v2``planning-turn-result.v2``plan-gdd.v2``plan-approval.v2`、四个 V2 command、`questionLimit=8` 及旧链路 `legacy-cutover.json` 封存边界;P1 尚未开工。
- 退役: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 结果丢弃和当前空能力快照。
@@ -1,7 +1,7 @@
# 策划会话 Runtime V2 接入与旧链路退役方案
- 日期:2026-09-03
- 状态:待开工本文是新生产实现的目标方案与阶段验收合同
- 状态:P0 合同冻结已完成,P1 待开工本文是新生产实现的目标方案与阶段验收合同
- 适用范围:AGC 桌面 App 的“做方案”入口、策划会话、GDD 产物与审批
> 本文只规定新策划 Agent 的生产接入和旧链路退役方式,不修改当前生产代码。现有 `project-supervisor-plan` / `project-planning` 链路在 V2 切换前仍是存量实现;V2 切换时旧链路直接封存,所有未完成旧会话强制失败,旧 Fast GDD 文档之后只作为历史记录依据。
@@ -164,12 +164,14 @@ AssistantText(text) # 当前策略只允许作为非法输出处理;未
### 4.1 V2 会话快照
建议持久化`planning-session.v2`
P0 冻结`planning-session.v2`
```json
{
"schemaVersion": "planning-session.v2",
"engine": "planning-session-v2",
"sessionId": "ps-...",
"projectId": "...",
"mode": "gdd",
"status": "awaiting_approval",
"turnIndex": 3,
@@ -182,7 +184,10 @@ AssistantText(text) # 当前策略只允许作为非法输出处理;未
"tools": [],
"skills": []
},
"processingSeconds": 123.45
"processingSeconds": 123.45,
"createdAtUtc": "2026-09-03T00:00:00Z",
"updatedAtUtc": "2026-09-03T00:02:03Z",
"lastError": null
}
```
@@ -192,9 +197,128 @@ AssistantText(text) # 当前策略只允许作为非法输出处理;未
- `questionCount` 只统计已经展示给用户的有效 question。
- `questionLimit` 由策略读取;当前值为 8,未来无限模式可为 `null`
- `revisionCount` 统计用户对当前产物发起的修改次数,不并入 questionCount。
- `capabilities` 记录本会话可用能力快照;当前必须为空数组。
- `capabilities` 记录本会话可用能力快照;当前 `tools``skills` 必须为空数组。
- `sessionId``projectId``createdAtUtc``updatedAtUtc` 是必填身份/时间字段;`lastError` 只保存安全错误分类和短摘要,不保存 Provider 原文、凭据或本地绝对路径。
### 4.2 状态
V2 会话 `status` 枚举冻结为:
```text
idle | planning | awaiting_user | awaiting_approval |
revision_requested | approved | rejected | provider_failed | stopped
```
`legacy_retired` 只属于旧链路封存投影,不写入 V2 Session。
### 4.2.1 V2 消息记录
完整会话记录使用 `planning-message.v2`,与 Provider 请求上下文分离:
```json
{
"schemaVersion": "planning-message.v2",
"messageId": "msg-...",
"clientTurnId": "turn-...",
"turnIndex": 3,
"atUtc": "2026-09-03T00:02:03Z",
"role": "assistant",
"kind": "question",
"payload": {}
}
```
`role` 冻结为 `user | assistant | system | tool``kind` 冻结为 `text | question | artifact | tool_call | tool_result | skill_reference | error`。当前 GDD 策略只产生 `text``question``artifact``error`,不执行或广告 `tool_call``tool_result``skill_reference`。未来启用 MCP/Skill 时使用已有 kind,不把工具结果伪装成普通 assistant 文本。
### 4.2.2 回合结果与能力快照
Provider 适配层输出 `planning-turn-result.v2`
```json
{
"schemaVersion": "planning-turn-result.v2",
"kind": "question",
"payload": {}
}
```
`kind` 冻结为 `question | artifact | assistant_text | tool_call | error`。当前 `GddPlanningPolicy` 只接受 `question``artifact(kind=gdd)`;其它结果按非法输出处理。
能力快照冻结为:
```json
{
"tools": [],
"skills": []
}
```
数组元素为稳定能力标识,必须去重并保持稳定排序;当前不得由模型修改。未来启用能力时由客户端/宿主在新回合开始前注入并重新记录快照。
### 4.2.3 当前策略的 payload 形状
`planning-message.v2``planning-turn-result.v2` 中的 `question` payload 冻结为:
```json
{
"id": "core_loop",
"header": "当前要决定:核心回路",
"question": "玩家每一局主要反复做什么?",
"options": [
{"label": "工作台设计迭代", "description": "先设计,再验证并回到编辑器修改。"},
{"label": "直接战斗验证", "description": "先进入战斗,再根据结果调整设计。"}
]
}
```
当前策略只要求 `options` 为 24 项、label/description 非空;不要求 A/B/“需要原型验证”固定顺序,也不把 `answerSource` 作为阻断条件。`question.id` 只作为当前问题标识,用户回答必须绑定当前 question 的 id。
`artifact` payload 冻结为通用产物包:
```json
{
"artifactId": "artifact-...",
"kind": "gdd",
"version": 1,
"status": "ready_for_approval",
"fingerprint": "sha256-...",
"payload": {
"schemaVersion": "plan-gdd.v2",
"game": {},
"decisions": [],
"prototypeValidationItems": []
}
}
```
`kind` 当前只有 `gdd`;未来增加其它产物类型时沿用同一产物包,不把会话状态改造成某一种产物的字段集合。`version` 在同一 V2 Session 内严格递增,`status` 当前使用 `ready_for_approval | approved | revision_requested | rejected | superseded`
### 4.2.4 V2 command DTO
四个 command 的输入/输出边界冻结如下:
| command | 必要输入 | 返回 |
|---|---|---|
| `start_planning_session_v2` | `projectPath``clientTurnId``prompt`、可选 `mode` | V2 Session 及本次回合结果 |
| `continue_planning_session_v2` | `projectPath``sessionId``clientTurnId``input` | 更新后的 Session 及本次回合结果 |
| `decide_planning_artifact_v2` | `projectPath``sessionId``artifactId``version``fingerprint``decisionId``action`、可选 `comment` | 审批结果和最新 Session 状态 |
| `hydrate_planning_session_v2` | `projectPath`、可选 `sessionId` | 只读 V2 Session、当前 question、当前产物和错误摘要 |
`input` 冻结为 `option``freeform``direct_draft``revision` 四种用户意图:
```json
{
"kind": "option",
"questionId": "core_loop",
"optionIndex": 1,
"optionLabel": "工作台设计迭代",
"text": "按 A 做"
}
```
Runtime 可以把 `A/B/C/D``1/2/3/4`、完整 label、“按 A 做”和“按第一个选项做”归一为 `optionIndex + optionLabel`;无法确定时才保留 `freeform`,不由旧 Supervisor 规则阻断。
`action` 冻结为 `approve | revise | reject`。所有 command 都只接受项目路径、V2 Session/turn/artifact 身份和用户输入,不接受 Supervisor root、child Run、delegation、claim 或 acceptance evidence 字段。
### 4.3 状态
```text
idle
@@ -217,7 +341,7 @@ planning
`provider_failed` 是可恢复的失败投影,不代表 GDD 被拒绝;重试时必须沿用当前 Session 和未完成的用户意图。`needs-reconciliation` 不作为 V2 的正常业务状态;只有发生不可判断的持久化冲突时,才进入单独的恢复错误并阻止自动覆盖。
### 4.3 问题上限语义
### 4.4 问题上限语义
`PLAN_MAX_TURNS=8` 的准确语义:最多向用户展示 8 个有效问题,而不是最多调用 Provider 8 次。
@@ -257,6 +381,17 @@ normalize_turn_result()
当前实际 Provider 配置、Responses 流式格式、超时、瞬态重试和凭据边界沿用 AGC 现有 Provider substrateV2 不改变当前 Provider 路由,也不引入新的第三方模型协议。
P0 冻结适配器的四个边界对象:
| 对象 | Runtime 可见字段 | 约束 |
|---|---|---|
| `PlanningProviderRequestV2` | `sessionId``turnIndex``mode``policyHint``messages``capabilities` | 不携带 Supervisor/child/delegation 身份;具体 API kind、URL 和凭据由 Provider substrate 持有 |
| `PlanningProviderStreamEventV2` | `type=text_delta\|completed\|failed`、可选 `text`/`result`/`error` | Provider 原始协议在 adapter 内归一;Runtime 不解析 OpenAI/Anthropic 私有字段 |
| `ContextBuildResultV2` | `messages``estimatedTokens``overflow` | 完整会话记录不等于请求上下文;`overflow=true` 时显式失败,不静默丢历史 |
| `CapabilitySnapshotV2` | `tools``skills` | 稳定排序、去重;当前必须为空,由宿主注入,模型不能修改 |
Provider adapter 只负责“请求、流式事件、稳定错误、用量/耗时”;是否接受 question/GDD、是否计入问题数和是否生成审批由 `PlanningPolicy` 决定。
### 5.2 完整会话与请求上下文分离
```text
@@ -312,7 +447,7 @@ game/fast_gdd.md
### 6.2 V2 GDD 与审批
V2 GDD 建议使用 `plan-gdd.v2`,只保存业务内容和 V2 自身身份:
P0 冻结 V2 GDD 使用 `plan-gdd.v2`,只保存业务内容和 V2 自身身份:
```json
{
@@ -338,7 +473,7 @@ sourceSessionRevision
createdByRunId
```
审批记录绑定 `version + fingerprint`
P0 冻结审批记录绑定 `version + fingerprint`,并使用 `plan-approval.v2`
```json
{
@@ -393,17 +528,23 @@ createdByRunId
### 7.2 V2 命令边界
建议新增独立命令(名称可在 P0 冻结)
P0 冻结新增以下独立命令
```text
start_planning_session_v2
resume_planning_session_v2
submit_planning_user_input_v2
continue_planning_session_v2
decide_planning_artifact_v2
hydrate_planning_session_v2
```
命令只接收项目路径、Session 标识、用户文本/选项和 V2 产物身份;不接收或生成 Supervisor 根 Run、delegation、acceptance evidence 等字段。
命令职责冻结为:
- `start_planning_session_v2`:创建或幂等启动 V2 Session,并提交首条用户需求。
- `continue_planning_session_v2`:提交用户对 question 的回答,或提交审批修改意见后的修订指令;重启恢复不单独创建 `resume` 命令。
- `decide_planning_artifact_v2`:提交当前最新产物的批准、修改或退回决定。
- `hydrate_planning_session_v2`:只读返回 V2 Session、当前产物和当前等待态。
命令只接收项目路径、Session 标识、稳定 client turn、用户文本/选项和 V2 产物身份;不接收或生成 Supervisor 根 Run、delegation、acceptance evidence 等字段。
### 7.3 UI 复用边界
@@ -448,14 +589,16 @@ hydrate_planning_session_v2
目标:把 V2 与旧链路的边界写成开发可执行合同。
状态:已完成(2026-09-03)。P1 可以按本节冻结内容开始编码。
任务:
| ID | 任务 | 产出 |
|---|---|---|
| P0-1 | 冻结 Session、消息、回合结果、产物和审批 DTO | V2 schema 草案、字段枚举和版本策略 |
| P0-1 | 冻结 Session、消息、回合结果、产物和审批 DTO | V2 schema、字段枚举和版本策略 |
| P0-2 | 冻结状态机、`questionLimit` 语义和重试规则 | 状态转移表、错误边界 |
| P0-3 | 冻结新旧并存与同项目单权威规则 | 路由/恢复决策表 |
| P0-4 | 冻结 Provider/ContextBuilder/Capability 插槽 | Rust trait/模块边界草案 |
| P0-4 | 冻结 Provider/ContextBuilder/Capability 插槽 | provider-neutral adapter 和模块边界 |
阶段验收:
@@ -463,6 +606,11 @@ hydrate_planning_session_v2
- 文档中不再出现“V2 先复用旧 Supervisor 再逐项放宽”的实现路径。
- 能明确区分完整会话记录、Provider 请求上下文、GDD 产物和审批记录。
- 明确旧会话如何封存、何时创建 V2,以及如何拒绝旧/V2 双活。
- 已冻结 `planning-session.v2``planning-message.v2``planning-turn-result.v2``plan-gdd.v2``plan-approval.v2` 的版本名及核心字段。
- 已冻结 `start/continue/decide/hydrate` 四个 V2 command 的职责;恢复不另建 resume command。
- 已冻结 `questionLimit=8`、内部 question 重试上限为 1、Provider 失败/非法输出不占 questionCount 的规则。
- 已冻结 `.agent/planning-v2/legacy-cutover.json` 的旧链路封存边界和 `legacy_retired` 投影语义。
- 已冻结当前 `capabilities.tools/skills=[]`,未来能力通过能力快照和消息 kind 扩展,不修改 Session 根结构。
依赖:无。完成后才能开始 P1。