diff --git a/apps/ai-game-creator-shell/src-tauri/prompts/runtime/roles/project-planning.md b/apps/ai-game-creator-shell/src-tauri/prompts/runtime/roles/project-planning.md index df797b2d2..bb22f4704 100644 --- a/apps/ai-game-creator-shell/src-tauri/prompts/runtime/roles/project-planning.md +++ b/apps/ai-game-creator-shell/src-tauri/prompts/runtime/roles/project-planning.md @@ -15,6 +15,7 @@ ## 低幻觉与 GDD 约束 +- 用户描述玩法类型、机制或“像某款游戏”时,不代表授权复刻该游戏。游戏名称、世界观、角色与单位名、阵营、资源、界面术语和视觉语言必须原创;不得沿用、翻译或近似改写现有游戏的专有名称、Logo、标志性布局与受保护视觉语言,也不得把它们写进 GDD 正文、决定台账或原型验证项。用户提到的相似作品只能作为抽象品类参考,`targetUsers.referenceGames` 同样不得填入受保护名称。你的工具面窄,但内容红线不因此放宽——GDD 是整条产线的上游。 - A、B 或自由填写得到的用户决定标 `confirmed`;用户选择“需要原型验证”标 `prototype_pending`;只有未提问、由你按默认建议填写的字段才标 `default_pending`,其 `answerSource=default`、`round=0`。不要把用户选择的 B 当成默认项。 - 用户在后续自由填写中推翻已确认决定时,保留用户答案原文,紧接被推翻的决定注明“已被第 N 轮回答推翻,以后者为准”,并在新决定 topic 中写明关系;不得改写、拆分或搬动原文。 - 只定义一个完整可玩闭环。MVP 不含多人、商城、服务器、开放世界、赛季、复杂社交、完整剧情或全量内容,除非用户明确改变范围。 diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/prompt.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/prompt.rs index 84546ac3e..e928ecef8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/prompt.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/prompt.rs @@ -927,6 +927,43 @@ mod tests { } } + #[test] + /// `common.md` 的原创性红线随 `$base` 分发给做游戏链路的每个专业 Agent,但 + /// 策划子 Agent 走 exact allowlist 的专用小 prompt、不拼 `$base`(理由见 + /// `game_creator_project_planning_tool_plan_system_prompt` 的注释),该条款 + /// 因此在 M1A-2 收窄工具面时被连带切掉——工具面窄是对的,内容红线跟着一起 + /// 消失不是。GDD 是整条产线的上游:策划稿里落进受保护名称,下游做游戏的 + /// Agent 即便个个守规也已经晚了。断言的是「策划子 Agent 实际收到的完整 + /// prompt」,不限定由哪一层提供,将来若把 common.md 拆成工具面与内容红线 + /// 两段再正常合成,这条同样成立。 + #[test] + fn project_planning_prompt_keeps_the_originality_red_line_common_md_carries() { + assert!( + required_runtime_prompt_section("common").contains("不代表授权复刻现有游戏"), + "common.md 的原创性红线是本断言的对照基线;它若被改写,必须一并复核策划 brief" + ); + let mut delivered = game_creator_agent_runtime_tool_plan_system_prompt_for_agent( + GAME_CREATOR_PROJECT_PLANNING_AGENT_ID, + "", + ); + delivered.push_str("\n\n"); + delivered.push_str(&game_creator_agent_runtime_role_overlay_prompt( + GAME_CREATOR_PROJECT_PLANNING_AGENT_ID, + None, + )); + for required in [ + "不代表授权复刻", + "必须原创", + "受保护视觉语言", + "referenceGames", + ] { + assert!( + delivered.contains(required), + "策划子 Agent 收到的 prompt 缺少原创性约束:{required}" + ); + } + } + #[test] fn project_planning_role_brief_is_isolated_to_its_manifest_overlay() { let planning = game_creator_agent_runtime_role_overlay_prompt(