@@ -1,5 +1,13 @@
# 决策记录
## 2026-09-21 渠道进安装身份:不同渠道的 AGC 包体在同一台设备并存
- 背景:渠道此前只决定更新端点(`plugins.updater.endpoints` )与渲染层平台 origin, `productName` / `identifier` 与渠道无关,于是所有渠道共用 `%LOCALAPPDATA%\陶泥儿` 安装目录、同一个卸载项(`HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\陶泥儿` ,另有 `HKCU\Software\genarrative\陶泥儿` )以及同一份 `%APPDATA%\world.genarrative.ai-game-creator` 数据目录。本机 0.1.48 安装实测:主程序二进制里只有 1 处 `agc/dev-win/latest.json` 、0 处 release 端点,说明渠道在产物里只体现为端点。后果是后装的渠道静默顶掉先装的渠道,并接管更新端点、平台服务器与本地登录态/项目数据。
- 决策:渠道同时决定**安装身份**。默认渠道 `dev` 保持基线 `productName = 陶泥儿` 、`identifier = world.genarrative.ai-game-creator` (既有安装目录、卸载项与升级链不断);其它渠道派生 `陶泥儿 <渠道显示名>` ( `release` → `陶泥儿 Release` )与 `world.genarrative.ai-game-creator.<渠道>` 。身份与更新端点必须在同一个构建期 `--config` 里注入,禁止分别回读默认值。窗口标题、macOS 产物名(`.app` / updater 归档 / DMG 卷名)、首装包选择与 Windows 提权 ACL 的 managed 识别范围同批跟随该身份。
- 边界:不做本地数据迁移或共享——切渠道等于换一个客户端;`release` 与自定义渠道首次以新身份安装,不接管、不迁移既有 `dev` 安装与本地项目,由用户自行决定是否卸载其一。
- 影响范围:新增 `apps/ai-game-creator-shell/scripts/channel-identity.mjs` ; `build-release.mjs` 、`build-macos-ci.mjs` 、`check-config.mjs` 、`agent-swarm-test-chat.mjs` 、`src-tauri/src/{main.rs,windows.rs,config.rs}` 与对应测试;主规范 `docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md` 。
- 验证方式:`node --test apps/ai-game-creator-shell/scripts/build-release.test.mjs release-oss.test.mjs prepare-macos-codex.test.mjs cargo-features.test.mjs` (64/64,新增渠道身份与渠道 DMG 首装选择用例)、`node apps/ai-game-creator-shell/scripts/check-config.mjs` (基线等于默认渠道身份、非默认渠道身份隔离)、`cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell -- config::private_path_elevation_policy_tests` ( 12/12,含基线/`<基线>.release` /`<基线>.beta-2` 与相似前缀反向断言)、`AGC_UPDATE_CHANNEL=release npm --prefix apps/ai-game-creator-shell run build -- --no-bundle --debug` (产物字符串实测 `陶泥儿 Release` × 1、`agc/release-win/latest.json` × 1、`world.genarrative.ai-game-creator.release` × 1、`agc/dev-win/latest.json` × 0)。真机双渠道安装、并存与各自更新尚未执行,按未验证项记录。
## 2026-09-21 项目快照按部署渠道分区,后台按渠道查看并按素材查询口径展示用户
- 背景:AGC 项目快照此前统一写在 `agc/project-snapshots/v1/{user}/{project}/` ,而开发与正式两套部署共用同一个 bucket(都默认 `agc-dev` )。结果是渠道混在一层前缀里:正式后台会列出开发渠道上传的项目,列表上也看不出项目属于哪个渠道;同时“项目工程”列表只有裸用户 ID,且用“加载更多”逐段追加,翻页与定位都困难。
@@ -11,6 +19,24 @@
- 未迁移的历史对象:`agc/project-snapshots/v1/` 下现存对象(只读核对过的两份历史清单)保留在 OSS,但不再写入、不再进入后台列表;需要取回时按旧前缀在 OSS 侧直接读取,确实要在后台看到时再单独开一个只读兼容视图。
- 验证方式:`cargo test -p platform-oss snapshot` 7 passed(渠道校验、键布局、v2 根渠道枚举、v1 历史键仍必须私有);`cargo test -p api-server project_snapshot` 18 passed/1 ignored(渠道失败关闭、游标跨渠道拒绝、用户昵称/陶泥号解析、归档与配额回归);`cargo test -p api-server protected_route_matrix` 、`route_contract` 通过(新路由纳入后台鉴权矩阵);`npm run admin-web:typecheck` 与 `npx vitest run apps/admin-web/src` 202 passed。
## 2026-09-21 Godot 模板入库与按模板建项的 Godot 分流
- 背景:模板库此前只有网页(html)、Cocos 与 Unity 占位,`runtime` 白名单早就接受 `godot` ,但既没有 Godot 模板,也没有按模板建项的 Godot 分流——Godot 模板即使上传,建项也会落到 Web 分支,写出 `game/index.html` 占位入口并让 `godotProjectRoot` 为空。
- 决策(模板内容):新增四个仓库内手写的 Godot 4.7 模板 `godot-empty-2d` 、`godot-empty-3d` 、`godot-hello-world` 、`godot-platformer-2d` , `entry` 统一为 `project.godot` 。模板只用内置 `ui_*` 输入动作、GL Compatibility 渲染,并用 `Polygon2D` / `BoxMesh` 搭可视骨架,不引入外部贴图或音频二进制;不打包 `.godot/` 缓存与导出产物。
- 决策(建项分流):`create_project_from_installed_template_at` 在复制模板后按工程文件分流——Cocos 更新自身身份后走 Cocos 导入,Godot 先改写 `project.godot` 里 `[application]` 段的 `config/name` (只改这一行,其余字节逐字保留)再走既有 Godot 导入,写入 `godotProjectRoot: "."` ,其余继续走 `init_local_game_project_at` 。分流靠工程文件识别,不新增只读 `entry` 或 `runtime` 字段的契约。
- 原因:Godot 工程身份是 `project.godot` 所在目录,与 Cocos 的 `package.json` 身份同一类问题;复用既有导入流程能同时拿到相对根记录、`.agent` 初始化与「不生成 Web 占位入口」这三条既有保证,并且与 Cocos 分支保持对称。
- 影响范围:`apps/ai-game-creator-shell/template-library/v1/godot-*` (新增模板源)、`apps/ai-game-creator-shell/src-tauri/src/template_library.rs` 、`.../src/project/manifest.rs` ( `apply_godot_project_display_name` )、`.../src/project/manifest/import_tests.rs` 、`docs/【模板规范】AGC模板包组织指南-2026-09-21.md` 、`docs/technical/【技术方案】AGC模板库与模板建项-2026-09-17.md` 。
- 验证方式:本机 Godot `4.7.2.stable` 对四个模板逐一做「主场景实例化 + 3 帧 + GDScript `--check-only` 」,平台跳跃模板另做真实物理试玩(落地 y=627.99、1 秒右移 320px、跳上平台 y=515.93、三枚金币全收集);Rust 定向回归 `import_tests::rewrites_only_the_godot_display_name_line` 、`import_tests::keeps_a_godot_project_without_a_display_name_line_untouched` 、`template_library::tests::godot_template_creates_native_project_with_relative_root_and_display_name` 与既有 Cocos/Web 建项回归;发布走 `--only godot-*` 定向合并。
## 2026-09-21 Godot 工作区发现放宽与内置插件行去掉手动启动
- 背景:2026-08-10 “发现与歧义决策”把「一层多命中」和「`project.godot` 必须是普通文件」两条定为失败关闭。这两种布局都会让整个工作区被判成「没有 Godot 工程」,而 `PluginHost::list` 只按发现结果过滤,结果是 Godot 内置插件在设置→扩展 里直接消失,用户看不到任何可诊断入口。
- 决策(发现):根目录命中仍然优先;根未命中时一层直接子目录多命中改为按目录名排序取第一个,`godotProjectRoot` 记录该相对目录名,结果确定且可复现。`project.godot` 允许是符号链接 / Windows reparse point / 硬链接,判据改为「链接目标解析后是文件」,目录与悬空链接仍不算命中。工作区根本身是链接、候选子目录是链接、二层及更深不递归这三条边界不变。
- 决策(界面):设置→扩展 的内置插件行去掉手动「启动 / 停止」按钮。启动本来就由项目切换时的 `startAvailableAgcEditorPlugins` 自动完成,手动按钮只是第二个可绕过入口;停止改走该行的启用/禁用开关,`set_agc_plugin_enabled(false)` 会停止插件并断开编辑器连接。导入扩展行的启动按钮保留,因为导入扩展没有自动启动路径。
- 原因:Godot 插件列表是按项目过滤的,发现失败等于功能静默消失;把不确定性收敛成一个确定的排序选择,比让用户面对空列表更好。链接放宽只作用于只读的工程标记文件,受管描述文件、运行缓存与项目目录的链接拒绝规则不动。
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs` 、`.../src/commands.rs` (错误文案)、`.../src/project/manifest/import_tests.rs` 、`.../src/tests/project.rs` 、`apps/ai-game-creator-shell/src/features/runtime-config/RuntimeConfigDialog.tsx` 、`docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` §3.8、`docs/technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md` 、`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` 。
- 验证方式:`cargo test --locked -p genarrative-ai-game-creator-shell --bin genarrative-ai-game-creator-shell -- project::manifest::import_tests::` 与 `-- tests::project::` ;前端 `agc:typecheck` 与 `runtime-settings` / `pluginHost` 套件。
## 2026-09-21 模板正文目录门禁:CLI 打包与后台上传同一份段名单
- 背景:模板包组织指南把 `.agent/` 、`.git/` 、`node_modules/` 、根目录 `dist/` 等列为「不要放进 ZIP」,但两条发布路径此前只校验路径安全与 `entry` 是否存在,放进去的东西会跟着建到用户项目里(模板自带 `.agent/` 会让新项目继承一个陌生身份)。这条约定只靠作者自觉。
@@ -8250,7 +8276,7 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
## 2026-08-10 AGC 打开现有 Godot 项目
- 项目双根决策(2026-08-14 更新):项目组只保留通用“打开项目 / 新建项目”,不再提供独立 Godot 入口。用户选择目录始终是工作区根,也是 `.agent` 、Session、Runner、沙箱、通用文件工具和外围资料的唯一授权根;实际 Godot 根由根目录或一层直接子目录中的普通文件 `project.godot` 唯一确定,并以工作区相对 `godotProjectRoot` 记录,根目录使用 `.` 。不得把 Runtime 根切换成 Godot 子目录,也不得复制工程或建立第二套工作区。
- 发现与歧义决策:根目录命中优先;根未命中时只检查一层直接子目录,唯一命中才通过,多个命中在任何 `.agent` 写入前失败关闭。候选目录与工程文件拒绝符号链接和 Windows reparse point,二层及更深不递归。未来只有 Godot 专属命令显式使用经过校验的相对 Godot cwd。
- 发现与歧义决策:根目录命中优先;根未命中时只检查一层直接子目录,唯一命中才通过,多个命中在任何 `.agent` 写入前失败关闭。候选目录与工程文件拒绝符号链接和 Windows reparse point,二层及更深不递归。未来只有 Godot 专属命令显式使用经过校验的相对 Godot cwd。( 2026-09-21 部分取代:多命中改为按目录名排序取第一个,`project.godot` 允许链接并按目标判定;候选子目录与更深层的边界不变,见本文件「2026-09-21 Godot 工作区发现放宽与内置插件行去掉手动启动」。)
- 元数据决策:首次导入只在工作区根创建并保留 `.agent/manifest.json` 、`.agent/agent.db` 、`.agent/logs/` 与 `.agent/runtime/` ;不得创建默认 Web 原型的 `game/` 、`assets/` 、`memory/` 、`exports/` 。已有有效 `.agent` 项目继续复用身份;缺失或错误的可推导 `godotProjectRoot` 只在 Godot 打开边界按唯一文件布局校准,歧义时不改写。
- Windows 锁文件决策:提升权限进程新建 `.agent/.manifest.json.lock` 时,Windows 可能把 owner 设为 `Administrators` 。仅在固定锁路径已取得不共享独占句柄并确认是普通、非 reparse、单链接文件后,才初始化为当前 `TokenUser` ;随后再次复核句柄并执行原有 owner/DACL 校验,不放宽既有异常对象的安全规则。
- 运行决策:Godot 项目提交给 Project Supervisor 时使用 `standard` Run Profile,避免触发 Web 专用 `game/index.html` 、HTTP preview 与自主 Web 完成门。Godot 编辑器启动和内嵌运行预览不在本切片范围。