冻结策划会话 Runtime V2 P0 合同
固定 Session、消息、回合结果、GDD 产物和审批记录的 V2 schema。 固定四个 V2 command、输入归一化和 questionLimit=8 语义。 固定 Provider adapter、ContextBuilder、能力快照及未来 MCP/Skill 扩展边界。 固定旧 Supervisor 链路 legacy-cutover 封存和未完成会话强制失败规则。 标记 P0 完成并同步项目决策记录。
This commit is contained in:
@@ -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` 为 2~4 项、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 substrate;V2 不改变当前 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。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user