文档:冻结策划节点身份常量并更正提问权限判据

裁定策划节点 agentId 为 project-planning、Supervisor 做方案入口 source
为 project-supervisor-plan(旧预留值 project-supervisor-plan-chat 作废,
避免字面未变而语义已改导致接错代码路径)。据此更新第 3 节注册表与第 4 节
拓扑图。

更正一处此前判断错误:standard 的 ready-task 调度器
start_game_creator_agent_background_task_with_source_at 向 _with_link_at
传 task_link = None,节点无 parent,source 也不在黑名单,因此
validate_user_input_action_owner 会放行它调用 user.input_request。
只有 autonomous 那个调度器才显式写 parent。所以策划节点不得直接提问是
产品约束的自律要求(否则问答会落进它自己的会话、Supervisor 上下文里
没有内容),必须由 exact allowlist 主动排除并以回归钉死,不能指望
Runtime 兜底。第 1.1 节、D10 与第 19 节第 2 条同步更正。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 12:29:16 +00:00
parent 6119060dc0
commit 331441534d
@@ -40,7 +40,9 @@
1. **策划不能跑在 `autonomous-game-build` 下。** `user.input_request` 被两层拦死且判据只看 run profile、不看 agent 身份——广告层 `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_policy_snapshot.rs:198-215` 按 profile 剔除并推进 `denied`;执行层 `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs:2604-2616` 直接判 `NeedsReconciliation`。**父 Supervisor 自己也在禁令内。**
2. **硬闯的后果是整条工作流永久瘫痪,不是单次失败。** `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_execution.rs:1157``runtime.status` 写成 `failed`,而 `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:685-693` 的根活跃判定只认 `pending | running | waiting-for-confirmation | waiting-for-user-input`,此后任何 ready task 都起不来,须人工核对。
3. **不能只给策划节点单独换 profile。** `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/run_configuration.rs:264-266` 明文「子 Run 不能切换父 Run 的 Run Profile」,且 profile 是 run 绑定时 CAS 锁死的终身属性。
4. **策划节点作为下游有 parent,不能自己向用户提问。** `apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367-394``validate_user_input_action_owner` 三路 OR 拒绝任何带 `parent_agent_id / parent_run_id / delegation_id` 的 run
4. **策划节点在 `standard` 下其实「能」自己提问,但「不得」这样做——理由是产品约束,不是机制阻拦。** 两个调度器的血统不同:autonomous 的 ready-task 调度器在 `task_start.rs:905-907` 显式写 `parent_agent_id / parent_run_id`,节点必然被 `validate_user_input_action_owner``apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367-394`)拒绝;而 **standard 的 ready-task 调度器 `start_game_creator_agent_background_task_with_source_at``task_start.rs:141-160`)向 `_with_link_at` 传入 `task_link = None`,节点无 parent**,其 source `agent-ready-task-scheduler` 也不在该函数的黑名单内,`agentId` 又不以 `child-` 开头——三路判据全不命中,**它调用 `user.input_request` 会被放行**
因此本方案不能依赖这道门来约束策划节点。若放任它自己提问,问答消息会按 `apps/ai-game-creator-shell/src-tauri/src/user_input.rs:494-530` 落进 `project-planning` 自己的会话文件,Supervisor 的上下文里一个字都没有,直接违反下文第二条产品约束。所以 **`user.input_request` 必须由策划节点的 exact allowlist 主动排除**,并以回归用例钉死——这是本方案里少数几个「Runtime 不会替你拦、必须靠 allowlist 自律」的地方。
#### 新拓扑(替代 D6
@@ -118,7 +120,7 @@ M0 三个代码工作包无一行按 D6 编写,**不需要为新设计回退
| D7 | 本期不实现知识图谱;`basis`、知识 provider trait、composition 槽位可以预留,但 v1 数据必须为 `null`,空字段不渲染。 |
| D8 | GDD 不含引擎字段;平台事实固定由 Runtime 注入,Agent 不得向用户提问或修改。 |
| D9 | **取代 D6。** 立项策划是独立 `agentId` 的下游工作流节点,由 manifest ready-task 调度器在 Supervisor 下游启动,需登记 agentCatalogProject Supervisor 以新的可信 source 承载「做方案」入口并保持唯一顶层 root;父子 run profile 必须同为 `standard`——不是为了复用顶层通道,而是因为 `autonomous-game-build``user.input_request` 的禁令按 profile 生效、父子皆不可提问,且子 Run 不能切换父 Run 的 profile。 |
| D10 | 策划节点自身有 parent、不得直接调用 `user.input_request`。问询走「Runtime 直投」:策划节点提交结构化决策字段,Runtime 创建 **owner 为 Project Supervisor** 的 pending,会话消息落 Supervisor 会话、结构化 observation 落策划节点,二者是同一 `AgentRuntimeUserInputRecord` 的两路投影。Supervisor 的 Provider 不参与提问。 |
| D10 | 策划节点**不得**直接调用 `user.input_request`——注意这不是 Runtime 拦得住的:standard ready-task 调度器不写 parent,该调用会被放行,因此必须由 exact allowlist 主动排除并以回归钉死。禁止的理由是产品约束:直接提问会把问答落进策划节点自己的会话,Supervisor 上下文里什么都没有。问询走「Runtime 直投」:策划节点提交结构化决策字段,Runtime 创建 **owner 为 Project Supervisor** 的 pending,会话消息落 Supervisor 会话、结构化 observation 落策划节点,二者是同一 `AgentRuntimeUserInputRecord` 的两路投影。Supervisor 的 Provider 不参与提问。 |
## 3. 合同名称注册表
@@ -126,13 +128,15 @@ M0 三个代码工作包无一行按 D6 编写,**不需要为新设计回退
| --- | --- |
| UI 阶段名 | `立项策划` |
| 英文称呼 | `plan phase` |
| Persona 名 | `立项策划 Agent` |
| durable source | `project-supervisor-plan-chat` |
| Rust source 常量 | `AGENT_RUNTIME_SUPERVISOR_PLAN_CHAT_SOURCE` |
| run profile | `standard` |
| Prompt composition | `supervisorPlanChat` |
| Prompt source kind | `SupervisorPlanChat` |
| 原生 action tool | `plan.submit_gdd` |
| 工作流节点名 | `立项策划 Agent`2026-08-12:不再是 persona,见 D9 |
| **策划节点 agentId** | `project-planning`(登记 agentCatalog`project-` 前缀标明项目级、不属任何专业组,故不与 design 组的 `design-director` / `design-foundation` 混淆) |
| **策划节点 durable source** | `agent-ready-task-scheduler`(复用现役 standard ready-task 调度器,不新增 source |
| **Supervisor 入口 durable source** | `project-supervisor-plan`(与 `-gui` / `-cli` / `-game-chat` 同族;2026-08-12 取代原预留值 `project-supervisor-plan-chat`,**旧字符串作废不得沿用**,避免字面未变而语义已改导致接错代码路径) |
| Rust source 常量 | `AGENT_RUNTIME_SUPERVISOR_PLAN_SOURCE` |
| run profile | `standard`Supervisor 根 run 与策划节点必须同为此值,见 D9) |
| Prompt composition | 策划节点 `projectPlanning`Supervisor 入口沿用现役 supervisor composition(其 Provider 不参与提问,无需专用 persona 稿) |
| Prompt source kind | `ProjectPlanning` |
| 原生 action tool | `plan.submit_gdd``plan.request_decision`(后者为 2026-08-12 新增:策划节点提交结构化决策字段,替代它不可能拥有的 `user.input_request`,见 D10 |
| pending kind | `gdd-approval` |
| 审批 Tauri command | `decide_game_creator_plan_gdd` |
| 审批动作 | `approve \| revise \| reject` |
@@ -172,13 +176,17 @@ M0 三个代码工作包无一行按 D6 编写,**不需要为新设计回退
```mermaid
flowchart TD
U["用户"]
subgraph SUP["Project Supervisor 顶层通道"]
PLAN["立项策划 Agent<br/>source=project-supervisor-plan-chat<br/>profile=standard<br/>composition=supervisorPlanChat"]
subgraph SUP["Project Supervisor 顶层 root run(三个入口 source"]
SPLAN["做方案入口<br/>source=project-supervisor-plan<br/>profile=standard"]
BUILD["完整构建 Supervisor<br/>source=project-supervisor-gui 或 project-supervisor-cli<br/>profile=autonomous-game-build"]
CHAT["game-chat Supervisor<br/>source=project-supervisor-game-chat<br/>profile=autonomous-game-build"]
end
U --> PLAN
PLAN --> GDD["不可变 GDD + approve receipt"]
U <-->|"唯一对话对象;问答落 Supervisor 会话"| SPLAN
SPLAN -->|"ready-task 调度(standard,无 parent 链接以外的特权)"| PLANNODE["立项策划节点<br/>agentId=project-planning<br/>source=agent-ready-task-scheduler<br/>profile=standard<br/>composition=projectPlanning"]
PLANNODE -->|"plan.request_decision 提交结构化决策字段"| RELAY{{"Runtime 直投<br/>创建 owner=Supervisor 的 pending"}}
RELAY -->|"会话消息投影"| SPLAN
RELAY -->|"observation 投影"| PLANNODE
PLANNODE --> GDD["不可变 GDD + approve receipt"]
GDD -->|"用户动作:开始完整制作"| BUILD
U -.->|"直接开建"| BUILD
BUILD --> DAG["现行 16 任务 DAG"]
@@ -1416,7 +1424,7 @@ receipt 永远压过 stale pending:一旦该版本存在有效 receiptpendi
## 19. 安全不变量与构建验证边界
1. 不放松 `autonomous-game-build``user.input_request` 的现行禁等待防线;多轮策划只发生在 top-level standard plan run。
2. **2026-08-12 按 D9 拆写,取代原「plan source 四项工具、跳过 collaboration 强制委派」)** 做方案链路的工具边界分两层:**Supervisor 根 run** 以新可信 source 承载入口,工具面按现役 `standard` deny-list 模型,但其 Provider 不参与向用户提问(问询由 Runtime 直投创建 owner 为 Supervisor 的 pending);**策划工作流节点**有 parent,其 action 工具广告与执行双门都必须是 exact allowlistMCP 为空,且**不含 `user.input_request`**(它有 parent`validate_user_input_action_owner` 会拒),改以提交结构化决策字段的专用工具替代。原表述中的「跳过 Supervisor collaboration 强制委派」被直接反转——策划节点恰恰是被 Supervisor 调度的下游,具体清单待第 1.1 节批二随命名裁决落笔。
2. **2026-08-12 按 D9 拆写,取代原「plan source 四项工具、跳过 collaboration 强制委派」)** 做方案链路的工具边界分两层:**Supervisor 根 run** 以新可信 source 承载入口,工具面按现役 `standard` deny-list 模型,但其 Provider 不参与向用户提问(问询由 Runtime 直投创建 owner 为 Supervisor 的 pending);**策划工作流节点** action 工具广告与执行双门都必须是 exact allowlistMCP 为空,且**必须主动排除 `user.input_request`**——standard ready-task 节点无 parent`validate_user_input_action_owner` 不会拦它,排除是产品约束的自律要求而非 Runtime 兜底,须以回归用例钉死;改以 `plan.request_decision` 提交结构化决策字段。原表述中的「跳过 Supervisor collaboration 强制委派」被直接反转——策划节点恰恰是被 Supervisor 调度的下游,具体清单待第 1.1 节批二随命名裁决落笔。
3. `.agent/planning/**``game/fast_gdd.md` 唯一写者是 Runtime;任何 Agent 通用写工具都不能触达。
4. GDD、receipt 追加不可变;index、session、Markdown 和 UI 只作有限投影,不能反写权威事实。
5. approve receipt 是构建信任根;Agent 文本、“已批准”状态缓存、Markdown 徽标或 UI 内存都无批准权。