diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index ac1fb0192..fba7df647 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -7,12 +7,12 @@ - 被 `build.rs` 比对的 `specialist_nodes` 集合只来自 `manifest.agent_catalog.groups[].roles[]`(`build_support/runtime_prompt_bundle.rs:387-398`),不遍历 `agentCatalog` 的其它顶层键。 - `project-supervisor` 本身就是「catalog 成员但不是种子 DAG 任务」的既有先例:`runtime_adapter.rs` 的 `build_game_creator_runtime_agent_catalog`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_adapter.rs:4-38`)先单独 push 一个 supervisor 的 `AgentDescriptor`,再遍历各组角色。 - `AgentDescriptor::metadata()` 目前零生产调用,`game_creator_runtime_agent_catalog()` 唯一生产调用点(`runtime_state.rs:1491`,即 `normalize_game_creator_runtime_agent_id`)只做 `.get(agent_id).is_some()`;`AgentCatalog::iter()` 也零生产调用——当前没有任何代码枚举 runtime catalog,`project-planning` 登记后不会泄漏进「做游戏」团队清单或路由清单。 - - 但仅做 catalog 登记不足以让 D11 可执行:`prompt.rs` 的 `game_creator_agent_role_definition`(`apps/ai-game-creator-shell/src-tauri/src/agent/prompt.rs:661-679`)硬编码「非 supervisor 即 group 角色」二分,`project-planning` 落入 else 分支返回 `None`,两个调用方(`provider_request_builders.rs:536-539`、`prompt.rs:416-417`)都会把 `None` 转 `Err` 中断,报「未知 Agent 模板:project-planning」——这是本次调研发现的 **blocking** 缺口,不是 catalog 登记本身能解决的。 - - 另有两处 **needs_change**:`task_ops.rs` 的 `task.create`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs:335-363`)在拿不到角色定义时把 group/role 静默兜底成 `Design`/`"Agent"`,会污染任务审计;`delegation.rs` 的 `agent.spawn_isolated` 校验(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/delegation.rs:1396-1412`)只排除 `child-` 前缀和 supervisor 本体,`project-planning` 登记后会被任何持有该工具的 Agent 当作动态孵生模板,与 D11「只能由 Supervisor 通过 `agent.delegate` 静态委派」的设计意图不一致。 + - 但仅做 catalog 登记不足以让 D11 可执行:`prompt.rs` 的 `game_creator_agent_role_definition`(`apps/ai-game-creator-shell/src-tauri/src/agent/prompt.rs:661-679`)硬编码「非 supervisor 即 group 角色」二分,`project-planning` 落入 else 分支返回 `None`,两个调用方都会把 `None` 转 `Err` 中断——`provider_request_builders.rs:536-539` 报「未知 Agent 模板:project-planning」,`prompt.rs:416-417` 报「未知 Agent:project-planning」(两处错误文案不同,均已逐行核对代码原文,非同一字符串)——这是本次调研发现的 **blocking** 缺口,不是 catalog 登记本身能解决的。 + - 另有三处 **needs_change**(第三处为 2026-08-13 对抗性复核独立扫描补记,前两处调研阶段已发现):`task_ops.rs` 的 `task.create`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs:335-363`)在拿不到角色定义时把 group/role 静默兜底成 `Design`/`"Agent"`,会污染任务审计;`delegation.rs` 的 `agent.spawn_isolated` 校验(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/delegation.rs:1396-1412`)只排除 `child-` 前缀和 supervisor 本体,`project-planning` 登记后会被任何持有该工具的 Agent 当作动态孵生模板,与 D11「只能由 Supervisor 通过 `agent.delegate` 静态委派」的设计意图不一致;`task_start.rs` 的 `collect_game_creator_agent_runtime_agent_ids`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:3-28`)与 `game_creator_agent_role_definition` 同构的二分硬编码(显式插入 supervisor id + 无条件遍历 16 个组角色 task_id),是核心恢复驱动 `read_game_creator_agent_runtimes_at`(`entrypoints.rs:756`)与三处安全网(崩溃恢复扫描 `recovery_scan.rs:448`/`:687`、steer 级联取消 `steering.rs:800`、委派回执兜底对账 `delivery.rs:1287`)的枚举来源,`project-planning` 不会被这三处发现,重启/steer/兜底对账场景下会静默变孤儿任务;委派首轮任务本身是同步起跑、不受此影响,故不算 blocking。此前的「排雷提示」只核实过 `agent.route_manifest` 与前端团队清单是硬编码字面量、结构上安全,未覆盖这条独立的动态遍历路径,是本轮复核前的调研遗漏。 - 决策:`project-planning` 在 `prompts/runtime/manifest.json` 的 `agentCatalog` 下登记为与 `supervisor` 平级、**不进 `groups` 数组**的独立条目(`id`/`taskId=project-planning`);descriptor metadata 取值——`groupId="project-planning"`(自引用伪 group id,绝不复用 `"design"`,避免与 design 组中文 label「策划组」语义碰撞)、不设 `groupLabel`(照抄 supervisor 先例)、`roleLabel` 跟随角色定义、`toolId="agent.runtime.project-planning"`(跟随 supervisor 的组外单节点命名族)、`capabilityAuthority="game-creator-tool-policy-snapshot"`(与全部现有条目相同,无需新值)。由此 `specialist_nodes`、16 任务种子 DAG、`new_game_creation_app_seed_tasks()`、`build.rs` 三者均不需要改动,「做游戏链路一行不动」得以成立。composition 复用现役 `runtime` composition,不需要单独配置;`briefPathName` 只是运行时文件名 token,缺文件不报错,但格式与全局唯一性仍受编译期 `validate_file_name`/`validate_agent_catalog` 约束。 - 编译链路要改的位置(M1 落地范围,本轮不动):`build_support/runtime_prompt_bundle.rs` 的 `struct AgentCatalog` 加 `planning` 字段、`validate_agent_catalog` 镜像 supervisor 的单 role 约束/去重/防冲突集合/显式校验调用、`compile_manifest` 的 `catalog_task_ids` 链入 `planning.roles`、`render_agent_catalog` 镜像 supervisor 专属四个产物;`runtime_adapter.rs:4-38` 镜像 push 一段 `AgentDescriptor`;连带隐藏耦合 `pass_artifacts.rs` 的 `agent_role_memory_relative_path_for_task`(335-347 行)需加第三条 `project-planning` 分支,否则运行时报「未知 Agent 任务」。 - **本轮范围声明(与 M1 的边界)**:本条只冻结登记机制、更新技术方案文档第 3.1 节与第 23.1 节,**不改 `manifest.json`、不改 `runtime_prompt_bundle.rs`、不改 `runtime_adapter.rs`、不改任何 `.rs` 文件**。理由:`project-planning` 目前没有 prompt、没有任何路径能调用它,现在注册 catalog 而不同步处理上面的 blocking 缺口,等于给发布产物加一个「看似已登记、一调用就硬失败」的死重身份;注册代码应与 M1 的 prompt/source 一起落地。 -- 保留待处置(M1 范围,非本条待裁决):`prompt.rs` 的 `game_creator_agent_role_definition` 角色身份合成缺口(blocking);`task_ops.rs` 的 group/role 误分类兜底(needs_change);`delegation.rs` 的 `agent.spawn_isolated` 放行面扩权(needs_change);`pass_artifacts.rs` 的内存路径解析缺口(M1 必须同步处理)。 +- 保留待处置(M1 范围,非本条待裁决):`prompt.rs` 的 `game_creator_agent_role_definition` 角色身份合成缺口(blocking);`task_ops.rs` 的 group/role 误分类兜底(needs_change);`delegation.rs` 的 `agent.spawn_isolated` 放行面扩权(needs_change);`task_start.rs` 的 `collect_game_creator_agent_runtime_agent_ids` 恢复/steer/对账枚举缺口(needs_change,2026-08-13 复核补记);`pass_artifacts.rs` 的内存路径解析缺口(M1 必须同步处理);`runtime_adapter.rs` 的 `game_creator_runtime_agent_catalog_matches_the_existing_role_directory` 测试(91-121 行)断言 catalog 精确等于 `{supervisor} ∪ 16 组角色`,`project-planning` 登记后需同步更新其期望集合,否则 M1 落地当天编译测试即失败。 - 关联文档:`docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md` 第 3.1 节(新增小节)、第 23.1 节(原「`project-planning` 的编译期 agentCatalog 登记方式与 `build.rs` 一致性校验」待裁决项已降级为「机制已定稿,代码落地属 M1」);关联决策:本文件下方同日「立项策划 D9 二次作废、D10 作废」条(D11、第 1.1 节「D11 新拓扑」第 6 条)。 ## 2026-08-13 立项策划 D9 二次作废、D10 作废:改为 Supervisor 静态委派子 Agent(D11);静态委派澄清轮次与返工深度拆分定稿(WP1) diff --git a/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md b/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md index 5444632a1..e54782999 100644 --- a/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md +++ b/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md @@ -258,6 +258,7 @@ composition/brief 相关的强制要求: 也就是说,**仅做本节描述的 catalog 登记,D11 的静态委派在执行层面完全跑不起来**;`game_creator_agent_role_definition` 需要一个平行于 supervisor 特判的 `project-planning` 分支,这是 M1 必须一并落地的代码,不属于本轮「不改任何 .rs」的范围。 - **needs_change**:`task_ops.rs` 的 `task.create` 工具(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/task_ops.rs:335-363`)在拿不到角色定义、且调用方未显式传 `group`/`role` 时,把 group 兜底成 `Design`、role 兜底成 `"Agent"`,而不是报错或识别「无 group」。`task.create` 对所有 `agent_id`统一开放,`project-planning` 一旦调用它且未显式带参数,会被静默记成「Design 组 / Agent 角色」任务写进 manifest.json,污染 6 组任务审计和按 group 聚合的面板,且无任何报错提示误分类。 - **needs_change**:`delegation.rs` 的 `agent.spawn_isolated` 校验(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/delegation.rs:1396-1412`)只排除 `child-` 前缀和 supervisor 本体,其余 catalog 成员一律放行为合法的 isolated 模板。`project-planning` 登记后会自动满足这个放行条件,于是任何持有 `agent.spawn_isolated` 权限的 Agent(不只是 Project Supervisor)都能拿它当模板动态孵生隔离子实例——这与 D11「`project-planning` 只应由 Supervisor 通过 `agent.delegate` 静态委派」的设计意图不一致,是登记后新增的隐性能力扩权,需要在 M1 与「blocking」项一并处理,不能默认「反正没人这么调」。 +- **needs_change(2026-08-13 对抗性复核补记)**:`task_start.rs` 的 `collect_game_creator_agent_runtime_agent_ids`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:3-28`)与 `game_creator_agent_role_definition` 是同构的二分硬编码——只显式插入 supervisor id(8 行),再无条件遍历 `GAME_CREATOR_AGENT_GROUP_DEFINITIONS` 插入全部 16 个组角色 task_id(19-23 行,不看当前是否有活跃任务),`project-planning` 既不是 supervisor、也不是组角色、也不是 `agent.spawn_isolated` 产生的动态孤立实例,天然不进入这个集合。此函数是核心 Runtime 推进/恢复驱动 `read_game_creator_agent_runtimes_at`(`entrypoints.rs:756`,被 `commands.rs`/`swarm_cli` 调用)与三处安全网的枚举来源:崩溃恢复扫描(`recovery_scan.rs:448`、`:687`)、root run 被 steer 时的级联取消(`steering.rs:800` 的 `cancel_goal_contract_root_descendants_at`)、委派回执兜底对账(`delivery.rs:1287` 的 `reconcile_game_creator_agent_delegate_receipts_at`,由 `recovery_scan.rs:1102` 触发)。经追踪 `agent.delegate` 派发路径(`delegation.rs` 里对 `start_game_creator_agent_background_task_with_link_at` 的调用),委派首轮任务是同步直接起跑的,不依赖这个集合,因此不属于「首轮即挂」的 blocking 类;但一旦应用重启、Supervisor 根 run 被 steer、或首轮结果的直接投递失败需要兜底对账,`project-planning` 的委派状态都不会被这三处安全网发现和处理,会静默变成孤儿任务,且与第 23.1 节「plan run 是否允许 steer」这条既有待裁决项直接相关(提供了其未验证交互的具体机制证据)。M1 需要给这个函数补一个与「group 角色无条件收录」对称的第三条分支;`runtime_adapter.rs` 里 `game_creator_runtime_agent_catalog_matches_the_existing_role_directory` 测试(同文件 91-121 行)断言 catalog 成员集合与 `{supervisor} ∪ 16 组角色` 精确相等,`project-planning` 登记后这条测试会立即失败,M1 需同步更新其期望集合,不能靠这条测试的失败倒逼才发现遗漏。 - **benign(不阻塞,仅记录)**:前端 `projectProfessionalAgentLabel`(`apps/ai-game-creator-shell/src/features/agent-runtime/model.ts:1496-1529`)的关键字匹配落不到 `project-planning`,会退化成直接显示原始 `agentId`。纯展示层缺口,不影响功能,M1 顺手补一条分支即可。 - 未来提醒(写入代码前必须核对,本轮不改):`pass_artifacts.rs` 的 `agent_role_memory_relative_path_for_task`(`apps/ai-game-creator-shell/src-tauri/src/agent/generation/pass_artifacts.rs:335-347`)也是「先特判 supervisor、再遍历 group」的同构硬编码,若不加第三条 `project-planning` 分支,运行时对它调用会落入 346 行的 `Err("未知 Agent 任务")`。 - 排雷提示(供未来维护者,非本轮改动项):全仓库检索确认,当前没有任何生产代码枚举 runtime `AgentCatalog`(`.iter()` 零生产调用),前端「团队」清单(`agentPresentation.ts` 的 `groupConfigs`)与 `agent.route_manifest`(`delivery.rs`)都是硬编码字面量/精确字符串判断,结构上不会把 `project-planning` 带进「做游戏」团队清单或路由清单。但**未来如果有人写「遍历 AgentCatalog 生成 UI 团队卡片/prompt 团队成员清单/任何 route 白名单」这类代码,必须显式按 `groupId ∈ {design, balance, art, audio, code, publishing}` 六个真实组过滤,或显式排除 `project-planning`(和 `supervisor`)这两个组外单节点**——这也是坚持 `groupId` 必须自引用为 `"project-planning"`、不能复用 `"design"` 的根本原因。