【清理】退役命令/能力/提示词残留与权限策略存量兼容-2026-10-06 #659
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景与为什么不在 PR #650 / Issue #649 里做
chore/rust-compile-warnings)的验收口径是编译告警清零 + 门禁 + 名实一致审计;本文三块都是行为 / 契约 / 存量数据兼容问题,改动跨packages/shared、server-rs/crates/shared-contracts、src-tauri/src/project、prompts/**,混入会让 review 与回滚粒度变差。范围(三块,均为
d2b2cad04实测)块 A · 权限策略存量兼容(原 §C.0)
A.1 机制(已复核,行号为本轮实测)
apps/ai-game-creator-shell/src-tauri/src/main.rs:789const PROJECT_PERMISSION_POLICY_PATH: &str = ".agent/policy.json";apps/ai-game-creator-shell/src-tauri/src/project/verification.rs)::793 read_project_permission_policy_at—— 文件不存在 →ProjectPermissionPolicy::default()(impl Default在:772-783:denied_commands为空,confirm_commands由:776-780从GAME_CREATION_APP_COMMANDS中只取permission == Confirm的 id 派生);serde_json::from_str::<ProjectPermissionPolicy>→:811 policy: normalize_project_permission_policy(policy)?;:841 normalize_project_permission_policy→:844/:845对denied_commands/confirm_commands各调normalize_policy_command_ids;:846起把PROJECT_PERMISSION_MANDATORY_CONFIRM_COMMANDS补进 confirm;随后去重(confirm 中的 denied 项移除);:865/:867对agent_policies同构处理;:877 normalize_policy_command_ids::884用GAME_CREATION_APP_COMMANDS.iter().any(|command| command.id == command_id)判存;不匹配即:888 return Err(format!("不支持的内置命令:{command_id}"))—— 是Err,不是静默过滤、也不是原样保留。:815 write_project_permission_policy_at→:820 normalize_project_permission_policy(policy)?→ 落盘 →:832写审计recordType: "project.policy_write"→ 回读返回。:898 enforce_project_permission_policy_rejection→:902调read_project_permission_policy_at→:903 .map_err(|cause| ProjectPermissionRejection::PolicyUnavailable { cause })?;另有:917 enforce_project_permission_policy、:925 enforce_project_auto_permission_policy走同一读取路径。:786-791PROJECT_PERMISSION_MANDATORY_CONFIRM_COMMANDS("project.git_commit"在:787,另有command.start/command.stdin/command.terminate);全 crate 只有两处引用:定义:786与消费:846(在normalize_project_permission_policy内)。.agent/policy.json含不在GAME_CREATION_APP_COMMANDS里的 id,则任何策略读取都返回Err→PolicyUnavailable,表现为该项目权限门动作(denied/confirm 判定、自动权限判定)全部被拒,错误面携带「不支持的内置命令:」原因。A.2 触发概率:有实证路径 + 实际是否触发不可判定
agent.route_manifest,删除于 2026-08-24 的532c6d51f,TS 与 Rust 同步;其余变化全是新增(2026-06-25 时 29 条 → HEAD 67 条,单调增长)。write_project_permission_policy_at(:815)在落盘前先:820 normalize,未知 id 会先Err;前端策略面apps/ai-game-creator-shell/src/features/project-workspace/projectCommandPolicy.ts:22-52的commandId类型即GameCreationAppCommandDescriptor['id'](:1导入),只能取契约内 id。532c6d51f落盘、且确实写入过agent.route_manifest的存量策略文件」,或用户手工编辑过的文件。.agent/policy.json(建议在修法落地前做一次只读采样,结果不写入本文)。A.3 修法(落到函数与行号)
:877-895):把:888的return Err(...)改为「收集并跳过」,签名扩为返回(保留 id, 丢弃 id)(或新增normalize_policy_command_ids_tolerant),由normalize_project_permission_policy在:844/:845/:865/:867四处消费丢弃集合。:793-813):丢弃集合非空时,在读路径里复用:815的写回(:820normalize、write_game_creator_private_file、:832审计形态),新增一条recordType: "project.policy_migrate"审计(字段带droppedCommandIds)。插入点::811的 normalize 之后、构造 view 之前。:786-791):project.git_commit(:787)在 67 条注册表内,属合法 id,本块不是缺陷、无需清理(见块 C);若要防漂移,可在:846循环处加「清单必须是注册表子集」的构建期/测试期断言,而不是运行时跳过。verification.rs现有唯一测试模块是:949-950 #[cfg(test)] mod npm_build_tests(首个用例:954,只覆盖 npm 构建校验),没有策略相关用例,需新增模块或用例。建议 4 条:①存量文件含已删 id → 读取成功且丢弃集合非空;②执法不再返回PolicyUnavailable;③写回后文件不含已删 id 且新增project.policy_migrate审计;④同一未知 id 只被记录一次。A.4 已停驻的实现(本轮复核)
.worktrees/chore/retired-command-residue(分支chore/retired-command-residue,基于9f4c7d763)有未提交改动:src/project/verification.rs(+227/-18)与src/project/conversation.rs(+27)。其verification.rsdiff 已实现 A.3 的第 1、2、5 点形态:normalize_policy_command_ids(root, …)增加root参数、读时迁移与回写、以及「兼容窗口 / 关闭条件」注释(注释里点名project.git_commit/project.patchset/project.git_inspect/agent.*),并新增 6 处测试。本轮未发现新增policy_migrate审计记录(在该 diff 内 greprecordType/policy_migrate/dropped无命中),也未发现对PROJECT_PERMISSION_MANDATORY_CONFIRM_COMMANDS(:786-791)的改动——即 A.3 第 2 点的审计部分与第 3 点未覆盖(该结论以本轮 grep 范围为限)。块 B · 退役能力文案与提示词文本
B.1 capabilities 41 条真实存在(双侧契约 + 测试 + 门禁)
packages/shared/src/contracts/gameCreationApp.ts:96export const GAME_CREATION_AGENT_CAPABILITIES = […:223] as const satisfies readonly GameCreationAgentCapabilityDescriptor[];server-rs/crates/shared-contracts/src/game_creation_app.rs:118pub const GAME_CREATION_AGENT_CAPABILITIES: [GameCreationAgentCapabilityDescriptor; 41] = […:193。area/title/platforms零不一致(os-workspace-sandbox是唯一带platforms: ['linux']的条目)。packages/shared/src/contracts/gameCreationApp.test.ts:297expect(GAME_CREATION_AGENT_CAPABILITIES).toHaveLength(41);(同文件:293-401另有逐条断言);Rustserver-rs/crates/shared-contracts/src/game_creation_app.rs:1658capabilities_cover_standard_agent_runtime_needs(:1659断言长度 41,1697-1741逐项)。apps/ai-game-creator-shell/scripts/check-config.mjs:1212-1216assertContractRecordsMatch('AI game creator shell capability contract', parseTsCapabilities(sharedContractSource), parseRustCapabilities(rustSharedContractSource));与:1206-1210的 command 契约门禁并列(解析器分别在:362/:375)。GAME_CREATION_AGENT_CAPABILITIES的引用只有:上述两份定义、两份测试、check-config.mjs的两处解析器与门禁调用;apps/ai-game-creator-shell/src内按capabilit(不区分大小写)检索命中的都是插件能力(src/app/types.ts:97)、资源编辑能力(src/features/.../resourceEditModel.ts:17)与 CSS(src/styles.css:5797),与本清单无关。docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md:1337写「共享契约提供GAME_CREATION_AGENT_CAPABILITIES和内置命令权限枚举;开发模式会展示能力列表」——后半句与代码不符(无任何消费方),应同步改口径。B.2 状态拆分(现役 21 / 部分现役 7 / 已退役未兑现 13)
判定方法:只看 AGC 客户端(
apps/ai-game-creator-shell/src-tauri)是否还有实现锚点(宿主/工具/命令/模块/常量的可执行符号),并用全仓(排除docs/与prompts/)交叉确认;只存提示词文本、契约常量或追踪 DTO 的,归「已退役未兑现」。chat(src/agent.rs:56 direct_game_creator_home_codex_chat)、file-upload(src/desktop.rs:625)、built-in-commands(src/project/verification.rs:776/src/project/conversation.rs:1228消费GAME_CREATION_APP_COMMANDS+command.run_limited/project.verify实现)、provider-web-search(web_search_enabled)、mcp-tools(src/desktop.rs:538 start_game_creator_external_mcp)、run-lifecycle(src/desktop.rs:214+runner/**)、short-term-memory(src/commands.rs:4659)、long-term-memory(src/commands.rs:4682)、conversation-history(src/project/conversation.rs)、local-artifacts(src/asset_generation_tasks.rs)、project-checkpoints(src/project/checkpoint.rs+project.checkpoint/restore/diff)、project-index(src/commands/desktop.rs:1111的enforce_project_permission_policy(root, "project.index")+src/main.rs:790 PROJECT_INDEX_PATH)、local-preview(src/preview.rs:247)、canvas-project-sync(src/features/project-workspace/projectCommandPolicy.ts:43的canvas.project_sync+canvas.asset_import实现)、persistent-runner(run_external_agent_runner_server)、command-exec(src/command_exec.rs)、os-workspace-sandbox(src/command_sandbox.rs,仅 linux)、command-output-read(src/command_output.rs)、guardrails(verification.rs:917)、project-policy(src/main.rs:789+ 策略链)、trace-log(src/main.rs:1039 append_application_log_line)。project-supervisor(常量/配置面在config.rs:115/:4301、main.rs:779/:896,编排运行时无实现)、context-compaction(cli.rs:113 auto_compact_token_limit等配置在,Agent Runtime 压缩 DTO 已退役)、task-decomposition(task.create/task.update工具 0 实现,但 seed task /GameCreationAppTaskStateschema 在main.rs:43/:50)、tool-call-budget(main.rs:55仍导入GAME_CREATION_AGENT_TOOL_CALL_MAX,预算执行面退役)、quality-review(agent 目录仍在config.rs:131,运行时执行面退役)、persistent-process-sessions(command.start仅存于src/process_session/model.rs:250附近,command.poll/stdin/terminate只有策略字串)、browser-validation(preview.validate仅作命令字串/状态文案/前端归一:src/agent/codex_app_server/mod.rs:847/:5611/:5618/:5621、src/features/agent-runtime/model.ts:493;浏览器验证实现另在browser/**,该工具 id 未见接线)。orchestration(plan_game_creation_agent_pass0;AgentPass*仅追踪 DTOsrc/agent/generation/trace.rs:270/:411)、agent-loop(全部锚点含GAME_CREATION_AGENT_LOOP_MAX_PASSES在客户端与全仓非文档处 0 命中)、task-graph-agenda(AgentPassTaskGraphSnapshot仅 trace)、evaluator-repair-routing(route_game_creation_repair_issues0;仅GameCreationAgentRepairRouteTrace追踪类型)、multi-agent-collaboration(collaboration0 命中)、role-level-collaboration(AgentGroupDefinition仅生成常量/trace)、isolated-subagents(agent.spawn_isolated/writeScopes0 命中)、repair-loop-carryover(carryOver/repairOfDelegationId0 命中)、persistent-user-input(user.input_request0;仅注释提到已不在树上的agent/direct_runtime/user_input.rs)、llm-draft-generation(write_local_game_draft_at/draft_writer/LlmGameDraft0 命中)、repository-startup-context(repository_context顶层项已清空)、visual-inspection(image.inspect仅剩错误文案src/image_inspect.rs:111/:119/:125,agent-runtime 检查实现已删)、developer-window。developer-window的反向证据(值得单列):src/内不存在open_developer_window;scripts/check-native-shells.mjs:2739-2748与scripts/check-config.mjs:1851是负向门禁——源码里一旦出现fn open_developer_window(或open_developer_window(app.handle())?;即throw;docs/project-memory/shared-memory/decision-log.md:8281记载「原生壳配置检查必须拒绝恢复open_developer_window(app.handle())?自动调用」。即该能力不仅无实现,且被仓库显式禁止恢复。prompts/runtime/texts/native-tools.json的 51 个 tool id 中,18 个在src/**下 0 命中(update_agent_plan、respond_to_user、user.input_request、git.inspect、project.patchset、file.patch、task.create、task.update、command.poll、blackboard.write、agent.message、agent.delegate、agent.spawn_isolated、agent.goal_contract、agent.acceptance_update、agent.schedule_ready、agent.action_history、agent.run_status),另project.git_commit/command.stdin/command.terminate在客户端只命中策略字串。这些 id 的非文档/非提示词命中集中在packages/shared/src/contracts(契约)与少量server-rs(module-ai / api-server,属平台模块域,不是 AGC Agent Runtime)。B.3 提示词文本残留(真实存在)
apps/ai-game-creator-shell/src-tauri/prompts/(仓库根没有prompts/);prompts/runtime/下含manifest.json、common.md、texts/、supervisor/、provider/、platform/;prompts/根另有local-project-prompt-polish.md、automatic-project-name.md。prompts/runtime/texts/native-tools.json:19"project.git_commit.description": "在验证和审阅后创建只包含显式路径的本地 Git 提交。"prompts/runtime/texts/native-tools.json:20"project.patchset.description": "在一把项目锁内原子应用最多十二项多文件变更。"prompts/runtime/texts/runtime.json:71"patchset_contract"(project.patchset变更字段契约)prompts/runtime/texts/runtime.json:83"git_commit_protocol"(引用git.inspect的commitSnapshotFingerprint)prompts/runtime/common.md:9git.inspect 会返回 commitSnapshotFingerprint;…才能用 project.git_commit 的 message、显式 paths、expectedHead 和 expectedSnapshotFingerprint 创建本地提交。prompts/runtime/texts/execution.json:28(planning.sourcePayloadGuidance提到project.patchset)、prompts/runtime/texts/recovery.json:19(failed_playtest保留project.patchset)。B.4 消费方与连带面(修正上一轮的过度断言)
prompts/runtime/manifest.json:9"nativeTools": "texts/native-tools.json"(runtime在:17)。src侧prompt_text!实际只消费 5 个 catalog:directTools(62) /direct(40) /media(25) /projectContext(7) /design(7) /execution(6);nativeTools、runtime、recovery、goalContext、interaction、uiDesignDoc、generation均为 0 引用(git grep -F 'prompt_text!("nativeTools'= 0)。tests/runtime_prompt_bundle_build.rs:180断言的是 agentCatalog 的 toolId("toolId": "agent.runtime.project-supervisor"),该测试文件与tests/prompt_source_boundaries.rs对native-tools/nativeTools均 0 引用。所以:删改nativeTools/runtime的文本不必同步改这两个测试;只有改动manifest.json的 catalog 注册或章节结构时,才会牵动build_support/runtime_prompt_bundle.rs的构建期校验与这两个集成测试(那时必须同 commit 改)。scripts/build-gitea-rust-cache.sh与scripts/check-native-shells.mjs:按退役符号与目标名检索均为 0 命中 ⇒ 本块无需改动这两个脚本(本轮实测)。块 C · 契约里退役 id 的去留(决策项,不是缺陷)
C.1 事实
packages/shared/src/contracts/gameCreationApp.ts:27-29与 Rustserver-rs/crates/shared-contracts/src/game_creation_app.rs:39-41均含project.git_inspect(auto) /project.git_commit(confirm) /project.patchset(confirm);本轮逐项解析两侧:id 集合相等且顺序相等(顺序还被测试锁定:gameCreationApp.test.ts:90-91与game_creation_app.rs:1436-1439断言project.git_commit紧跟project.git_inspect)。packages/shared/src/contracts/gameCreationApp.test.ts:54expect(GAME_CREATION_APP_COMMANDS).toHaveLength(67);(另有:56-58断言三个 id 存在、:139-149断言其权限)。verification.rs:786-791)全部在 67 条内,其中project.git_commit是confirm。⇒normalize_policy_command_ids的Err(:888)不会被这一路径触发,不存在「第二处不一致」。project.git_inspect/project.patchset在src-tauri/src下 0 命中(工具注册表、命令处理、commands.rs均无;原git_inspect.rs/patchset.rs顶层项已清空),project.git_commit除策略字串verification.rs:787外 0 命中;只有契约(两侧 + 测试)与提示词文本仍在描述它们。C.2 两种选择的代价
选项 1:保留(推荐面:契约=权限与命令 id 命名空间,向后兼容)
check-config.mjs:1218起的assertCommandNamesSubset之类「Tauri handler ⊆ 契约」类断言不会因此失败(是子集方向),但「契约 id 都有实现」这一名实关系仍然不成立,需在契约文件里就地注明「保留占位:实现已退役」。.agent/policy.json里可能出现的这些 id(以及未来若重新实现)不需要额外的迁移或兼容窗口;块 A 的宽容分支风险面更小。选项 2:移除(两侧 + 测试 + 门禁同步改)
gameCreationApp.ts:27-29、Rustgame_creation_app.rs:39-41、两侧测试(gameCreationApp.test.ts:54的 67、:56-58、:90-91、:139-149;game_creation_app.rs:1409-1440相关断言)、game_creation_app.rs的数组长度注记(; 67]→; 64])。Err路径(这正是块 A 必须先落地的原因);同时verification.rs:787的project.git_commit也必须移除(否则反而成为非法 id 写入源)。native-tools.json的三条描述可同批删除。C.3 决策
本项需要人工决策(保留 vs 移除 vs 分两步:先做块 A 再移除)。本文只陈述代价,不给结论。
逐项修法(汇总)
d2b2cad04)文件:行:888Err→:903PolicyUnavailable);触发概率 = 有实证路径 + 实际不可判定:888改为跳过+收集)→ 读时迁移(:811后触发:815写回 + 新增project.policy_migrate审计)→ 4 条测试(verification.rs现有测试模块仅:949-950 npm_build_tests)→ 兼容窗口结束后删宽容src-tauri/src/project/verification.rs:793-813,815-839,841-875,877-895,898-903,917,925docs/technical/…实施计划-2026-06-24.md:1337的「开发模式展示」口径;② 依 B.2 的 21/7/13 处置文案(现役项保留、退役项删除或标注);③ 删native-tools.json:19/:20、runtime.json:71/:83、common.md:9的退役描述——纯文本改动无需同 commit 动runtime_prompt_bundle_build.rs(B.4)packages/shared/src/contracts/gameCreationApp.ts:96-223;server-rs/crates/shared-contracts/src/game_creation_app.rs:118-193;scripts/check-config.mjs:1212-1216;prompts/runtime/texts/{native-tools.json:19,20,runtime.json:71,83};prompts/runtime/common.md:9verification.rs:787同改,且前提是块 A 已落地)gameCreationApp.ts:27-29;game_creation_app.rs:39-41;gameCreationApp.test.ts:54,56-58,90-91,139-149;verification.rs:786-791验收判据(可勾选)
PolicyUnavailable③写回后文件不含已删 id 且新增project.policy_migrate审计 ④同一丢弃 id 只记录一次。.agent/policy.json只读采样一次,给出「是否存在含已删 id 的存量文件」的结论(结论写回本文 A.2,替换「不可判定」)。docs/technical/…实施计划-2026-06-24.md:1337口径已改。native-tools.json/runtime.json/common.md不再描述已退役能力;若改了manifest.json结构,则build_support/runtime_prompt_bundle.rs的构建期校验与tests/runtime_prompt_bundle_build.rs、tests/prompt_source_boundaries.rs同步通过。game_creation_app.rs长度注记、verification.rs:787同 commit 改完,且npm run check:config通过。npm run check:encoding通过;AGC crate bin 与--all-targets两口径不新增 warning(不新增#[allow])。风险与红线
.agent/policy.json是存量项目落盘数据;必须「读时宽容 + 迁移回写」,不得靠删除字段或强校验逼用户重建。#[allow]:仓库红线;出现 dead_code 时按 cfg 边界(cfg(test)/cfg(not(test)))或删除实现处理。prompts/**的连带面只有「结构级」才算连带:纯文本删改不牵动集成测试,改manifest.json的 catalog 注册或章节结构才会(B.4)。显式不做
chore/rust-compile-warnings(PR #650)与其告警口径。与 PR #650 / Issue #649 的关系
#![cfg_attr(not(test), deny(warnings))]生产口径门禁);本 Issue 在其后开工,避免同文件双线改动。附录 A:本轮核对记录(可复现)
git rev-parse HEAD→d2b2cad045db9c0713c1ba2377becc7280c1b6degameCreationApp.ts(96-223,41 条)与game_creation_app.rs(118-193,41 条)→ id 集合相等、顺序相等、area/title 零不一致git show <rev>:<path>提取 id 列表并做前后差分(TS 66 rev / Rust 67 rev,回 2026-06-25)→ 仅一次删除:agent.route_manifest@532c6d51f(2026-08-24);29 → 67 单调增长git grep -n PROJECT_PERMISSION_MANDATORY_CONFIRM_COMMANDS→ 仅:786定义与:846消费git grep -n -E "project\.(git_inspect|git_commit|patchset)"(排除 docs/prompts/契约)→ 仅verification.rs:787git grep -o -E 'prompt_text!\("[a-zA-Z]+'聚合 → directTools/direct/media/projectContext/design/execution;nativeTools等 7 个 catalog 0 引用check-config.mjs:1206-1216(command + capability 契约)、:1218(handler ⊆ 契约)、:1851(禁止open_developer_window自动调用);check-native-shells.mjs:2739-2748(同向负门禁)prompts实根ls -d prompts→ 不存在(仓库根);crate 内src-tauri/prompts/列举见 B.3附录 B:被推翻 / 修正的旧口径
git grep -i orphan0 命中,无任何 orphan 相关断言。toHaveLength(67)已不存在 ⇒ 条数口径失效」 —— 经核对不成立。反证:packages/shared/src/contracts/gameCreationApp.test.ts:54就是expect(GAME_CREATION_APP_COMMANDS).toHaveLength(67);。capabilities/*.json3 文件 / 17 permissions)」 —— 经核对不成立。反证:packages/shared/src/contracts/gameCreationApp.ts:96-223(41)+server-rs/crates/shared-contracts/src/game_creation_app.rs:118-193([..; 41])+ 两侧契约测试:297/:1658+ 门禁check-config.mjs:1212-1216。ACLcapabilities/*.json是 Tauri 权限清单,与这 41 条同名不同物。verification.rs:787-790)全部在 67 条注册表内,normalize_policy_command_ids的Err(:888)不会被该路径触发。runtime_prompt_bundle_build.rs:180断言 nativeTools 文本,改文本必须同 commit 改该测试」 —— 修正为::180断言的是 agentCatalog 的 toolId;nativeTools/runtime在src侧prompt_text!引用为 0,纯文本删改不牵动集成测试(B.4)。git grep -F '🔴'= 0),分档出处仍需人工确认或改用 B.2 的 21/7/13。:811/:820/:829/:832—— 本轮实测入口行号为:793(read)/:815(write)/:841(normalize)/:877(normalize_policy_command_ids)/:888(Err)/:898(reject)/:903(PolicyUnavailable)/:917/:925;:811/:820是函数体内的 normalize 调用点,:832是审计recordType行(正确)。附录 C:停着的本地工作树(本轮复核)
W:/workspace/Genarrative/.worktrees/chore/retired-command-residue仍存在,分支chore/retired-command-residue,HEAD =9f4c7d763(落后于d2b2cad04)。src/project/conversation.rs+27、src/project/verification.rs+227/-18,合计2 files changed, 254 insertions(+), 18 deletions(-)—— 与上一轮记录一致(该工作树另有他人的历史 stash:本轮git stash list为 20 条,上一轮记录的「11 条」已过期;接续前先确认不误 pop 他人 stash)。verification.rs改动已覆盖块 A 修法 1/2/5 的形态(normalize_policy_command_ids(root, …)、读时迁移 + 回写、兼容窗口与关闭条件注释,并新增 6 处测试);本轮未发现新增policy_migrate审计与对verification.rs:786-791的改动(A.4)。git -C .worktrees/chore/retired-command-residue diff > /tmp/retired-residue.patch;d2b2cad04新开工作树,git apply --3way该 patch;