合并:把 master 的告警清理与首页对话退役并进接单化分支
- 冲突 codex_app_server/mod.rs:保留类型化回合失败 DirectTurnRunFailure 与 EnvironmentNotReady 分类,接受删除 audit/metrics 参数 - 冲突 direct_runtime/mod.rs:保留类型化错误反馈循环与"交付报告只读一次",保留 check_direct_turn_preconditions,接受 master 的 turn_kind 贯穿与首页无项目对话退役 - 冲突 direct_runtime/user_input.rs:保留接单后发射器与 canonical 用户条目的新调用签名 - 删除:随 master 移除 direct_codex_audit、direct_turn_metrics 两个账本模块及其全部引用 - 删除:direct_codex_error_should_feedback 字符串判据与首页对话函数及其测试 - 调整:direct_codex_error_feedback_prompt 收成单参数,与已落地的提示词模板一致 - 修复:master 新插入的用户条目冻结块改用 DirectTurnError::turn_failed
This commit is contained in:
+2
-2
@@ -42,6 +42,7 @@
|
||||
- [DirectProject Codex 原始历史与异常恢复](<./technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md>):原始 Responses item 持久化、线程注入与异常回合收尾。
|
||||
- [DirectProject 对话历史单一事实源](./adr/【ADR】DirectProject对话历史单一事实源-2026-09-16.md):AGC 项目开发对话只以项目对话历史与运行态事件为真相源,聊天投影不落盘。
|
||||
- [DirectProject 独立聊天容器与工作台钱包布局](./adr/【ADR】DirectProject独立聊天容器与工作台钱包布局-2026-09-18.md):DirectProject 与 Supervisor 等路径分容器,钱包入口由项目工作台布局独立承载。
|
||||
- [退役 AGC 项目对话斜杠命令](./adr/【ADR】退役AGC项目对话斜杠命令与终端swarm chat入口-2026-09-22.md):AGC 项目对话与终端 swarm chat 均不再解析斜杠命令,终端聊天入口一并退役;实现、测试、门禁与文档承诺全部删除,命令 id 与权限位作为项目策略词汇表保留。
|
||||
- [引用候选由宿主注入](./adr/【ADR】引用候选由宿主注入-2026-09-22.md):引用输入区只接受宿主注入的引用 provider,素材选择面板独立成组件,附件芯片成为本轮附件唯一事实源。
|
||||
- [DirectProject 命令接单化](./adr/【ADR】DirectProject命令接单化-2026-09-23.md):命令只负责接单、事件流回答整轮结果;拒单前置、失败后置。
|
||||
- [DirectProject 命令接单化实施计划](./technical/【实施计划】DirectProject命令接单化-2026-09-23.md):四步落地顺序、每步不变式与验收;四步均已落地。
|
||||
@@ -55,8 +56,7 @@
|
||||
- [AGC 总版本号与发号](./technical/【技术方案】AGC总版本号与发号-2026-09-20.md):客户端版本号收口到 OSS `agc/global-version.json`,统一构建一次发号供各渠道共用,渠道高水位降级为断言。
|
||||
- [AGC 模板库与模板建项](./technical/【技术方案】AGC模板库与模板建项-2026-09-17.md):`templates/` 前缀的模板库契约、下载安装与「用模板建项目」链路。
|
||||
- [AGC 模板包组织指南](./【模板规范】AGC模板包组织指南-2026-09-21.md):模板 ZIP 的根目录结构、Cocos 工程保留项、禁止放入的内容、封面与体积上限、版本不可变与发布前自检。
|
||||
- [DirectProject 本轮附件路径映射](./technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md):Direct 首轮只映射附件原名与项目相对路径,不灌正文、不区别 GDD。
|
||||
- [Direct 回合行为审计账本](./technical/【技术方案】Direct回合行为审计账本-2026-08-31.md):Direct GUI 回合把 native 读 / MCP / 写文件落成项目内有界时间线,用于判断有没有打开本轮附件。
|
||||
- DirectProject 附件按 AGC 主实施计划的 canonical `userItem` 合同传递;旧 sidecar 路径映射方案已归历史,见文档生命周期索引。
|
||||
- [项目开发工作台 PRD](./prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md):当前工作台页面和验收边界。
|
||||
- [AGC 错误报告与诊断上传](./technical/【技术方案】AGC错误报告与诊断上传-2026-08-31.md):当前进程错误事件、应用级日志和管理员查看器合同。
|
||||
- [立项策划 Agent(Fast GDD)](<./technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md>):历史 V1 方案,仅用于追溯;旧 `project-supervisor-plan` / `project-planning` 入口、审批、恢复和测试均已删除。
|
||||
|
||||
@@ -16,6 +16,21 @@
|
||||
|
||||
- 输入区删除 `versions` / `activeVersionId` / `showTriggerButton` / `onReferencePickerOpen` / `skills`,`assets` 被注入的 provider 取代;`projectPath` 只保留给输入区自己的润色链路。
|
||||
- 输入区与宿主之间只留三个通用接缝:`providers`(引用来源)、`inputActions`(操作排里的宿主控件,例如 `@` 触发钮)、`submitSuppressed`(宿主浮层打开时 Enter 让位)。引用种类一个都不进输入区。
|
||||
- `provider.match` 必须是纯函数(输入区在渲染阶段调它取候选);懒加载走 provider 的可选 `onMenuQueryChange(query)`,由输入区在 `useEffect` 里回调,菜单关闭时收到 `null`。Skill 目录因此第一次敲出 `$` 时才读,渲染期不再有 invokes 或 ref 写入。
|
||||
- `provider.fuzzyLookup` 必须是纯函数(输入区在渲染阶段调它取候选);懒加载走 provider 的可选 `onMenuQueryChange(query)`,由输入区在 `useEffect` 里回调,菜单关闭时收到 `null`。Skill 目录因此第一次敲出 `$` 时才读,渲染期不再有 invokes 或 ref 写入。
|
||||
- 附件并入 `ChatReference`,编辑器收敛为单一引用节点类型,附件 chip 的 DOM 契约逐字保留;附件导入成功后以芯片进入正文,失败不插入;控制器不再持有附件数组,`MAX_CHAT_COMPOSER_ATTACHMENTS` 改为按草稿中的附件芯片数计算,导入进行中禁止发送。
|
||||
- 用户可见行为保持不变,唯一例外是已裁决的缺陷修复:非 DirectProject 宿主不再出现 `$` Skill 候选。
|
||||
|
||||
## 修订(2026-09-22):粘贴解析需要第二道只读缝
|
||||
|
||||
粘贴进来的纯文本要按同一套引用文本语法反解析回正文芯片,因此 provider 的两个查询能力按「模糊 / 精确」分开命名,各自说清自己的语义:
|
||||
|
||||
- `fuzzyLookup(query)`:候选菜单那条路——按 query 做包含匹配、大小写不敏感,并在 provider 内部截断到候选上限。名字写明它是模糊的,避免被拿去反查 token。
|
||||
- `lookup()`:精确查找那条路——某一刻 provider 真正能解析出的全部引用,不做模糊过滤、不截断,与菜单共用同一份候选来源;仍是纯函数,由输入区在粘贴事件里同步调用,数据没到就是空数组。
|
||||
|
||||
这不推翻本 ADR 的懒加载结论:`onMenuQueryChange` 仍是唯一的懒加载入口,粘贴解析**只用此刻就绪的候选**,不等待、不补读。Skill 目录因此还是「用户第一次敲出 `$` 才读」——冷启动时粘贴 `$名称` 就按字面文本保留(看得见、不是猜错),不为了粘贴去提前读盘。
|
||||
|
||||
附件与运行画面区域仍是静默 provider:它们没有候选,所以粘贴解析不认 `@附件名` / `@区域标签`,这两类 token 粘贴时逐字保留(附件与运行区域的身份来自文件与 run,纯文本重建不出来)。
|
||||
|
||||
歧义口径:同一个 token 对应多条引用身份(同名素材)时一律按文本保留;解析只认显示名逐字一致(不认扩展名、resourceId、大小写变体),未命中的 token 与其余文字逐字保留。
|
||||
|
||||
(本次把上一条同名决策里的 `match` / `candidates` 改名为 `fuzzyLookup` / `lookup`,语义不变;旧名不再保留。)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# 【ADR】退役AGC项目对话斜杠命令与终端swarm入口-2026-09-22
|
||||
|
||||
状态:已接受
|
||||
|
||||
## 背景
|
||||
|
||||
AGC(`apps/ai-game-creator-shell`)的项目对话曾把用户能力挂在「聊天输入 `/<cmd>`」上:除真正带执行语义的 `/history` 外,还累积了几十个只生成后续草稿或只读摘要的命令(`/brief`、`/status`、`/read`、`/trace`、`/art`、`/export`、`/cover`、`/remember` 等)。无 GUI 的终端 swarm chat 入口 `--swarm-chat` 另有一套控制命令(`/help`、`/agents`、`/status`、`/history`、`/compact`、`/resume`、`/goal`、`/quit`)。
|
||||
|
||||
这些命令的实际状态是:正式对话面已经换成 DirectProject 单容器,斜杠命令列表不再有渲染入口,`/history` 之外没有任何现役调用方;但命令字面量仍分散在控制器分支、`chatPromptPolish` 的 `/` 前缀绕过、命令参数校验文案、`projectSummaryConstants` 的命令清单、只服务已退役摘要面板的 `project-summary/*Summaries.ts`、构建期门禁 `scripts/check-config.mjs`、无人调用的 Tauri 能力清单命令、`swarm_cli` 的终端输入解析与帮助输出,以及多份权威文档的承诺里。
|
||||
|
||||
保留它的代价持续存在:每次调整对话形态都要同步维护这套死词汇表和它的门禁,而且「命令」一词在 AGC 里同时指用户斜杠命令与项目权限命令 id(`GAME_CREATION_APP_COMMANDS`)两件事,术语歧义会直接误导后续改动。
|
||||
|
||||
## 决策
|
||||
|
||||
- 斜杠命令语义整体退役,按「从未存在」处理:不保留入口、不做兼容提示、不写 tombstone,实现、专属测试、构建期门禁条目与文档承诺一并删除,历史由 Git 保存。
|
||||
- 删除项:Direct 聊天的 `/history` 精确匹配分支与 `reloadHistory`;`chatPromptPolish` 的 `/` 前缀绕过;`chatCommandMetadata`、`projectSummaryConstants.chatCommandHelp`、`memoryCommands.parseRememberInput` 等命令清单与参数解析;只服务退役 Supervisor 摘要面板、零外部调用的 `project-summary/*Summaries.ts` 与 `agentTrace.ts`;草稿回填死链(前端 `agentPresentation.ts` 的草稿推导与 Rust `suggested_canvas_tool_call`);无人调用的 Tauri 命令 `get_game_creation_agent_capabilities` 与 `get_limited_local_commands`;钉住上述字符串的门禁条目与专属测试。
|
||||
- 终端 swarm chat 入口连带其命令层整体退役:`--swarm-chat`、`src-tauri/src/swarm_cli.rs` 与整个 `swarm_cli/` 目录(`/help`、`/agents`、`/status`、`/history`、`/compact`、`/resume`、`/goal`、`/quit` 的解析、帮助输出、turn 派发、观察器、报告与专属测试)一并删除;`SwarmChatFlow`、`SwarmTurnObservation`、`SwarmTurnOutcome::Quit`、`SwarmConfirmationResolution::Quit`、`SWARM_TURN_*_ERROR`、只服务终端命令的 `agent.compact` / `agent.resume` / `agent.run_status` 校验(`swarm_cli/input.rs` 内那份)与 `print_runtime_response_stream_status` 也随之消失;同名权限 id 在现役 Tauri 命令与 Runtime 生命周期上的门禁保持不动。只服务终端交互内核的 `agent/interaction.rs` 整层(`AgentInteractionAction`、tool registry、`game_creator_agent_uses_interaction_kernel`、`decide_game_creator_agent_interaction_turn_for_session_at`、`AgentInteractionProviderStreamSink`)同样删除;其上仅存的自然语言 steer 决策路径 `decide_game_creator_agent_runtime_steer_at` 在收尾复查后一并删除(见「影响」的复查收尾)。
|
||||
- 保留项(它们不是斜杠命令):命令 id 注册表 `GAME_CREATION_APP_COMMANDS` 与 `GameCreationAppPermission`(Rust 运行期项目权限策略的词汇表;App 前端只用 `GameCreationAppCommandDescriptor` 类型表达权限判定与审计日志粒度,数组本体由 Rust 策略路径与跨语言一致性门禁消费)、`needsInitializedChatProject` 与项目权限策略链路、Rust 侧路径与路由的 `/` 前缀校验、`--agent-*` CLI 控制命令(Goal、steer、cancel、retry、context compact、resume、状态查询)与 Tauri IPC 注册。
|
||||
- 应用内项目对话的输入只剩自然语言回合(外加 `@` 素材引用与附件);需要动作时由 Runtime 工具、确认卡和既有 CLI 控制命令承接,不由聊天文本解析控制词。
|
||||
- 需要显式控制时改用现有 `--agent-*` CLI 命令:手动压缩是 `--agent-context-compact`,恢复扫描是 `--agent-resume`,Goal 生命周期是 `--agent-goal-*`。
|
||||
|
||||
## 备选方案与取舍
|
||||
|
||||
1. **只删正式用户窗口的入口,保留解析层**:看似省事,但命令字面量与分支继续存在,新对话形态仍要绕过它们,正是本次要消除的持续维护成本。
|
||||
2. **保留 `/history` 作为唯一命令**:它确实是唯一有执行语义的入口,但保留一个精确匹配的 `/` 语法就要求保留前缀绕过判断、命令被发现与文档承诺的整套口径;DirectProject 的历史重读改由重新进入对话/重新订阅自然完成,不需要用户输入控制词。
|
||||
3. **加兼容层(识别到已知命令时给提示或忽略)**:等于把死词汇表永久固化在解析层,与「按从未存在处理」相反,且会长期占据用户可见面。
|
||||
|
||||
## 影响
|
||||
|
||||
- 术语收敛:AGC 里的「命令」此后指项目内部命令 id 与权限位,「斜杠命令」作为已退役说法不再出现在权威文档与代码注释中。
|
||||
- 应用内项目对话的可见行为不变:正式对话面本来就不渲染命令列表,`/history` 之外没有可执行路径;删除后唯一的用户可见差异是输入以 `/` 开头时按普通文本处理。终端侧不再有 swarm chat 入口,也没有任何斜杠命令面。
|
||||
- 删除范围包含构建期门禁条目,因此不得为退役概念新增守卫测试或断言残留字符串的 check 条目;防止概念回归依靠架构边界(没有解析层可写)而不是字符串钉桩。
|
||||
- 复查收尾(同一决定的后续提交):配置向导里指向已删 npm 脚本的 `test:chat` 调用与失去含义的 `--configure-only` 开关、App 内 `请先用 /project …` 用户文案、`interaction.json` 中只服务已删交互内核的 7 个 prompt 键、harness 里因调用方被删而零引用的死导出,以及过期注释一并清理;无前端调用方的 Tauri 命令 `start_game_creator_agent_runtime_task` 随本次清理删除(`main.rs` 注册与 `check-config.mjs` 条目同步移除);`steer_game_creator_agent_runtime_task` 同时是 `decide_game_creator_agent_runtime_steer_at` 的唯一非测试入口,删掉该命令后整条 LLM steer 判定链(`agent/interaction.rs`、`runtime.interrupt_for_steer_decision`、`agent.runtime.steer_decision` 持久记录、`steer_decision_*` prompt 键与只测该链的专属用例)一并退役。
|
||||
- `.agent/logs/command.log`、项目权限确认卡与 `commandRuns` 属于项目命令审计,继续保留,不受本次退役影响。
|
||||
@@ -75,7 +75,8 @@
|
||||
|
||||
- 运行视窗必须占满中央工作区为游戏保留的可用区域。loopback 预览页通过客户端本地 preview server 注入的只读尺寸桥上报文档实际宽高;宿主只接受当前 iframe、当前 loopback origin 的固定版本消息,并将完整游戏文档等比缩放、居中放入视窗。iframe 首次适配后发生的真实内容增高或缩短仍必须被接受;仅浏览上下文宽高回灌或内容宽高未变化时保持当前状态,不触发重复渲染。
|
||||
- 窗口或中央区域尺寸变化后必须重新测量和适配;内容已经放得下时保持 `1:1`,不得无故放大。游戏文档宽高超过视窗时缩小整体画面,不显示 iframe 横向或纵向滚动条,也不得用单纯裁切替代完整展示。尺寸桥以根布局 `ResizeObserver` 为主,并在页面可见时每 `500ms` 至多探测 `512` 个元素作为绝对定位溢出的低频兜底;探测截断时不得用部分样本下调尺寸,viewport 耦合的 `100vh / 100% / bottom / right` 布局也不得形成自反馈。相同测量结果去重,不监听整页属性、文本或子节点突变;桥不读取项目正文、不修改 manifest、游戏文件或运行业务状态。桥脚本只能注入到真实 HTML 标签上下文,不能把脚本、样式、模板或注释中的 `</body>` / `</html>` 文本误判为结束标签;省略结束标签的 UTF-8 HTML 仍需安全注入。
|
||||
- 运行视窗下方继续保留“信息展示”和“数值微调”区域标题及原有面板高度;没有真实资源信息或已登记微调项时,内容区域保持空白,不显示示例字段、默认数值、未载入控件或功能说明,也不得因内容为空压缩两个面板。Agent 对话标题栏不显示头像图标,“与陶泥儿的对话”及副标题按标题栏左侧对齐,钱包和审批入口继续位于右侧。
|
||||
- 运行视窗右下角提供“全屏预览”:只把游戏画面那一格送进全屏,顶部页签、右侧对话和底部信息栏不跟着放大;再次点击该入口、按 `Esc` 或由宿主退出全屏都回到原布局。宿主没有 Fullscreen API 时整枚入口不渲染,不留点了没反应的按钮。
|
||||
- 运行视窗下方的信息栏只在**有真实内容**时存在(当前判据是**资源选中态**:在资源画布或浮层资源面板里选中一张资源后切到运行页签仍保留,信息栏渲染它的只读字段;运行画面上的“点选素材”只往对话插入引用,不改选中):没有内容时整栏不渲染,有内容时自动展开并可手动收起到只剩一行开合按钮;不显示示例字段、默认数值、未载入控件或功能说明。暂时没有数据源的区域(「数值微调」的登记表)不渲染区域标题与卡片,等编辑态登记表接进来后与内容一起出现。Agent 对话标题栏不显示头像图标,“与陶泥儿的对话”及副标题按标题栏左侧对齐,钱包和审批入口继续位于右侧。
|
||||
|
||||
- 数值修改立即写入当前项目的编辑态配置。
|
||||
- 当前已拉起的体验预览和测试切片不热更新;必须重新拉起后才能消费新值。
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# AGC 发行包分片续传上传实施计划
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | runtime-smoke-passed(存储原语、服务端入口、原生上传器、渲染进程接线与真实栈分片续传 smoke 均已落地) |
|
||||
| Date | 2026-09-23 |
|
||||
| Parent Milestone | `docs/project-memory/plans/【里程碑】AGC发行包分片续传上传-2026-09-23.md` |
|
||||
|
||||
## 修改边界与顺序
|
||||
|
||||
1. **存储原语(已完成)**:`server-rs/crates/platform-oss/src/lib.rs` 新增 `append_internal_object` / `append_internal_object_with_retry` 与 `OssAppendInternalObjectRequest` / `OssAppendInternalObjectResponse`;复用现役 V4 签名助手 `signed_request_builder`(查询串已参与签名)与 `run_internal_put_with_retry` 的可重试分类。`position = 0` 追加到末尾,`position > 0` 必须等于对象当前长度;返回 `next_position` 作为权威已收字节。
|
||||
2. **服务端入口(已完成)**:`server-rs/crates/api-server/src/modules/game_distribution.rs`
|
||||
- 新增 `GET .../package/upload-state`、`PUT .../package/chunk`、`POST .../package/complete`、`POST .../package/reset` 四个路由,沿用作者鉴权、`game-distribution:publish` 灰度开关与 `Idempotency-Key` 约定;
|
||||
- 分片大小 `PACKAGE_UPLOAD_CHUNK_BYTES = 8 MiB`,分片请求体放行量为分片大小 + 1 KiB;
|
||||
- 从整包 `PUT` 抽出共享收口 `confirm_validated_package`(声明比对 → 确认 → 结构化事件),两种入口共用;
|
||||
- 新增 `game_distribution_oss_client` / `game_distribution_package_object_key` / `staged_package_bytes` / `require_octet_stream_content_type` / `package_upload_offset` 辅助函数;偏移不一致返回 `409 PACKAGE_UPLOAD_OFFSET_MISMATCH` 与权威偏移;未收齐返回 `409 PACKAGE_UPLOAD_INCOMPLETE`;校验失败删除半包并落 `upload_failed`。
|
||||
3. **AGC 原生上传器(已完成)**:新增 `apps/ai-game-creator-shell/src-tauri/src/game_package_upload.rs`:内容寻址暂存(`<appData>/game-package-staging/<sha256>.zip`,重启后同包复用同一文件)、`upload-state → chunk → complete` 循环、409 权威偏移续传(响应丢失后按服务端已收字节对齐,不重放不跳段)、仅对传输/超时/408/429/5xx 退避重试(默认 4 次尝试)、`game-package-upload-progress` 进度事件;暂存路径必须落在暂存目录内。命令 `prepare_local_project_game_package` / `upload_local_project_game_package` 已注册,整包回传命令 `read_local_project_export_package` 退役(`read_local_project_export_package_at` 仍供暂存使用)。
|
||||
4. **渲染进程接线(已完成)**:`apps/ai-game-creator-shell/src/services/gameDistributionPublish.ts` 改为 `prepare`(拿摘要与暂存路径)→ 创建游戏 → 创建版本 → 原生分片上传 → 送审;`LocalProjectExportPackagePayload` 整包类型退役,改为 `StagedGamePackage` / `GamePackageUploadOutcome`;不再有任何整包字节进 IPC。
|
||||
5. **真实栈 smoke(已完成)**:本地 api-server + 真实 OSS bucket 上跑通「中断 → 续传 → 确认」。做法与证据:
|
||||
- 先用 `npm run dev:spacetime` 把当前模块发布到本地库(`genarrative-game-creator-dev`,自动迁移完成),再用 `npm run dev:api-server` 起 `127.0.0.1:8082`;
|
||||
- 本地库的 `feature_gate_config` 原本为空(发布开关默认关闭),用 `spacetime call … upsert_feature_gate_config` 写入 `game-distribution:publish enabled=true rollout=100`;
|
||||
- `GENARRATIVE_AGC_PUBLISH_E2E_BASE_URL=http://127.0.0.1:8082 npx vitest run apps/ai-game-creator-shell/tests/gameDistributionPublishLive.test.ts` → **1 passed / 3.9s**(发行包 9.0 MiB,跨 8 MiB 分片边界);
|
||||
- 用例断言实际发送过的分片偏移序列等于 `[0, 8388608]`:第一片只发一次,中断后的续传从权威偏移开始,不重放也不跳段;
|
||||
- api-server 侧同一轮日志:`package_chunk_stored offset=0 chunk_bytes=8388608 received_bytes=8388608 elapsed_ms=201`、`package_chunk_stored offset=8388608 chunk_bytes=1049210 received_bytes=9437818 elapsed_ms=82`、`package_confirmed package_bytes=9437818 file_count=3 oss_put_skipped=true elapsed_ms=884`。
|
||||
- 为了能指向本地栈,用例还补了两处基础设施修正:把客户端平台基址切到传入的 base URL(`setClientServerSelection({preset:'custom'})`),以及桥接层把 jsdom realm 的 `Headers` / `Blob` / `FormData` 降级成 Node 侧原生值(`FormData` 手工序列化为 multipart 字节,否则 OSS 直传回 405)。
|
||||
|
||||
## 不改的部分
|
||||
|
||||
- 网页端发布路径与整包 `PUT` 语义不变;`MAX_PACKAGE_BYTES`、展开量、单文件与文件数上限不变。
|
||||
- 未新增 SpacetimeDB 表或字段:已收字节的事实来源是 OSS 对象长度,版本状态机沿用既有 `awaiting_upload → uploaded → …`。
|
||||
- 未引入半包定时清理任务。
|
||||
|
||||
## 验证命令
|
||||
|
||||
- `cargo test -p platform-oss`(74 passed)
|
||||
- `cargo test -p api-server game_distribution`(23 passed,含新增 `package_chunk_size_stays_inside_declared_limits`、`package_upload_offset_requires_non_negative_integer`、`package_chunk_content_type_must_be_octet_stream`)
|
||||
- `cargo fmt --all -- --check`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`
|
||||
- `cargo test game_package_upload`(AGC 原生侧 4 passed:分片规划无缝无重叠、409 权威偏移解析、URL 拼接、内容寻址暂存与路径校验)
|
||||
- `npx tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit`、`npm run --workspace apps/ai-game-creator-shell typecheck`(含 `check-config.mjs` 的命令登记门禁)
|
||||
- `npx vitest run`(发布函数 6 passed、发布面板 9 passed、发布反馈 5 passed;真实链路用例在无 `GENARRATIVE_AGC_PUBLISH_E2E_BASE_URL` 时按设计跳过)
|
||||
- 待做:真实栈 smoke(本地 api-server + 真实 OSS bucket 上跑「中断 → 续传 → 完成」,含 `x-oss-next-append-position` 语义确认)
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- **对象可追加性**:`platform-oss` 之前没有追加写,首次真实调用需要在真实 bucket 上确认 `x-oss-next-append-position` 语义;失败时回滚点是 `platform-oss` 新增函数与四条路由(整包 `PUT` 不受影响,可独立回退)。
|
||||
- **半包对象**:分片写入直接落在版本键上,未完成时是半包。它不进公开目录、不服务发行网关;失败或作者重置时删除。若删除失败会记录 `package_staging_delete_failed` 告警,需要人工确认对象键状态。
|
||||
- **重置语义**:只有 `awaiting_upload` / `upload_failed` 允许重置,避免破坏已确认事实。
|
||||
- **内存**:完成动作按 200 MiB 上限回读整包再校验,峰值与整包 `PUT` 同量级;分片路径不再让整包驻留客户端。
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
- 允许修改:
|
||||
- `apps/ai-game-creator-shell/scripts/channel-identity.mjs`(新增,渠道身份单点定义)
|
||||
- `apps/ai-game-creator-shell/scripts/build-release.mjs`、`build-macos-ci.mjs`、`check-config.mjs`、`agent-swarm-test-chat.mjs`
|
||||
- `apps/ai-game-creator-shell/scripts/build-release.mjs`、`build-macos-ci.mjs`、`check-config.mjs`
|
||||
- `apps/ai-game-creator-shell/src-tauri/src/main.rs`、`src-tauri/src/windows.rs`、`src-tauri/src/config.rs`
|
||||
- 对应测试:`build-release.test.mjs`、`prepare-macos-codex.test.mjs`
|
||||
- 文档:AGC 更新主规范、共享记忆与本计划对
|
||||
@@ -47,3 +47,10 @@
|
||||
- 风险:非默认渠道首次以新身份安装,老 `dev` 用户不会自动迁移本地数据。回滚点:渠道身份只影响非默认渠道构建,撤销该渠道的构建产物即可,仓库侧无数据迁移。
|
||||
- 风险:窗口标题改为构建期产品名后,标题不再等于配置里的字面量。回滚点:去掉 `main.rs` 的标题覆盖调用,行为回到配置标题。
|
||||
- 风险:ACL managed 识别放宽到前缀族。回滚点:`is_game_creator_packaged_app_data_leaf` 收紧回单一直线值,但非默认渠道的提权修复会重新失败关闭。
|
||||
|
||||
## 2026-09-23 追加:dev 渠道展示名统一
|
||||
|
||||
- `dev` 渠道继续复用 `world.genarrative.ai-game-creator`,保证既有安装、升级链和 AppData 路径不变;展示名统一为 `陶泥儿开发版`。
|
||||
- `channel-identity.mjs` 是展示名单一来源。发布构建将同一 `productName` 同时注入 Tauri 安装配置、原生窗口标题和 `VITE_AGC_PRODUCT_NAME`;React 自绘标题栏及关于/运行时配置展示从该注入值读取。
|
||||
- 因此 Windows NSIS 默认生成的快捷方式、开始菜单/卸载注册表展示名随 Tauri `productName` 变为 `陶泥儿开发版`;未新增自定义注册表或快捷方式实现。
|
||||
- 静态 Tauri 基线配置同步为 `陶泥儿开发版`,本地壳与正式 `dev` 包的显示名保持一致。
|
||||
|
||||
@@ -33,3 +33,10 @@ Parent Milestone: `【里程碑】AGC统一错误诊断与验收反馈-2026-09-1
|
||||
- 若前端详情读取失败,仍展示安全 `publicText`,不阻塞错误终态。
|
||||
- 若素材身份无法映射,继续失败关闭并记录明确 code,不回退为路径字符串通过。
|
||||
- 回滚可删除新事件写入和详情入口,保留旧 `failure.json` 读取兼容。
|
||||
|
||||
## 2026-09-23 维护态错误展示补充
|
||||
|
||||
- `apps/ai-game-creator-shell/src/services/clientApi.ts` 解析并保留维护响应的 `error.code`、HTTP 状态与 `meta.requestId`,识别网关 `MAINTENANCE` 后广播客户端维护事件。
|
||||
- `apps/ai-game-creator-shell/src/components/modal/MaintenanceNotice.tsx` 在客户端根部统一展示不可被局部业务兜底替代的大弹窗;发布、上传、资源换签等共用 `requestClientApi` 的请求均进入同一出口。
|
||||
- 普通 500、资源损坏和本地 `blob:` 图片预览失败不自动归类为维护;图片换签接口在维护期间失败时会触发统一弹窗,但本地刚选中的图片预览仍不依赖后端。
|
||||
- 验收补充:维护期间发布接口不能只显示“创建平台游戏失败”等局部文案;维护弹窗出现一次即可覆盖并发失败请求,关闭后业务页仍可重试。
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# 引用粘贴解析实施计划
|
||||
|
||||
对应:[引用候选由宿主注入](../../adr/【ADR】引用候选由宿主注入-2026-09-22.md)(含 2026-09-22 修订节);决策记录见 `docs/project-memory/shared-memory/decision-log.md` 的 2026-09-22 条目。上一步的重构计划见 [引用输入区重构与宿主注入](【实施计划】引用输入区重构与宿主注入-2026-09-22.md),那份明确不含本项。
|
||||
|
||||
## 一句话交付与验收判据
|
||||
|
||||
把从用户消息气泡(或任何同口径文本)复制出来的 `@显示名` / `$名称` 粘贴进引用输入区时,原位重建同顺序的引用芯片;其余文字逐字保留。
|
||||
|
||||
验收判据:
|
||||
|
||||
1. 粘贴文本 → 引用:`@显示名` 与 `$名称` 逐字命中当前宿主注入的 provider 候选时原位换成芯片,一次 Ctrl+Z 整体回退,token 之外的每个字符(含换行与空白)原样保留。
|
||||
2. 逐字一致、不做兼容别名:不认 `@hero.png`、`resourceId`、大小写变体、全角 `@`;token 前后必须是行首 / 行尾或空白。
|
||||
3. 宁可不成芯片也不能认错:同名多候选(同一个 token 对应多条引用身份)一律按文本保留;未命中的 token 静默保留,不提示、不猜路径或文件名。
|
||||
4. 只有真的解析出引用时才接管:同 namespace 的 `application/x-lexical-editor` 负载、不含 token 的纯文本、图片文件粘贴一律放行编辑器默认导入,现有粘贴行为逐字不变。
|
||||
5. 附件与运行画面区域不参与粘贴解析(静默 provider 没有候选),它们的 token 粘贴时按文本保留。
|
||||
6. Skill 目录冷启动不阻塞粘贴:`lookup()` 是纯函数,目录没到就是空数组——冷启动时粘贴 `$名称` 保留为文本(不等待、不补读),用户敲过一次 `$` 后即可解析。
|
||||
|
||||
## 流程判定
|
||||
|
||||
本次是共享组件的一处行为增量 + provider 契约加两个可选能力,不动 schema、不动公开 API/DTO、不动后端;按轻量流程只建本实施计划,不新建主规范与里程碑规范(与上一步重构同一判定)。
|
||||
|
||||
## 提交切分
|
||||
|
||||
1. **反解析口径**:`resourceReferences.ts` 新增 `buildContentFromPastedText(text, references)`(粘贴侧唯一反解析;与 `buildContentFromTextTokens` 同一套边界规则),配规则矩阵单测。
|
||||
2. **provider 契约**:`reference-source/types.ts` 把菜单查询改名为 `fuzzyLookup(query)`、新增精确查找 `lookup()`(两者共用同一份候选来源);`resourceReferenceProvider` 给全量可提及候选,`skillReferenceProvider` 给去重后的 Skill 候选。
|
||||
3. **输入区接管**:`ResourceReferenceInput` 注册 `COMMAND_PRIORITY_CRITICAL` 的 `PASTE_COMMAND`,只在解析出引用时 `preventDefault` 并在一次 `editor.update`(`PASTE_TAG`)内按选区插入;配集成用例。
|
||||
4. **文档**:`CONTEXT.md` 术语、本计划、ADR 修订节、`docs/【功能说明】AGC聊天素材引用-2026-09-08.md` 与决策记录。
|
||||
|
||||
## 验证
|
||||
|
||||
定向:`npx vitest run apps/ai-game-creator-shell/tests/resourceReferences.test.ts apps/ai-game-creator-shell/tests/referenceSourceProviders.test.ts apps/ai-game-creator-shell/tests/resourceReferenceInput.test.tsx`;全量:`npm run typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。真实客户端手感(粘贴时的候选菜单位置、大段文本粘贴观感、Tauri 剪贴板只带图片时的行为)留待真机验收。
|
||||
|
||||
## 风险与回滚
|
||||
|
||||
- 解析接管会绕过 Lexical 的 `text/html` 富文本导入:只在文本里真的解析出引用时接管,取舍已在上一条判据里限定;要完全避开富文本场景可以后续按 `clipboardData.types` 再收窄。
|
||||
- 气泡里若出现与素材同名的 `@区域标签` / `@附件名`,粘贴会被认成素材引用——纯文本无法区分,属已知取舍。
|
||||
- 回滚按提交粒度 revert;canonical content 形状、provider 的既有能力与出站文本口径都不变。
|
||||
|
||||
## 执行状态(2026-09-22)
|
||||
|
||||
已完成:`buildContentFromPastedText` 与规则矩阵单测(命中 / 未命中 / 相邻中文 / 扩展名 / 大小写 / 全角 / 同名歧义 / 重复出现 / 换行 / 与显示口径互为逆运算);provider 的 `fuzzyLookup` / `lookup` 及用例;输入区 `PASTE_COMMAND` 接管与 5 条集成用例(粘贴重建芯片、未命中保持字面、纯文本走默认导入、Lexical 负载让位、Skill 冷启动保持字面且敲过 `$` 后可解析);文档同步。
|
||||
|
||||
未做(本次范围外):斜杠命令 `/` 解析、拖拽文本(drop)、附件 / 运行画面区域 / 文件路径 / URL / 剪贴板图片的解析、复制侧 `text/plain` 形态调整、扩展安装卸载后的目录即时失效。
|
||||
|
||||
## 追加执行状态(2026-09-23):前缀重叠按「引用名无空白」收口
|
||||
|
||||
自动评审留下的唯一破坏性项(`@hero` 与 `@hero v2` 互为前缀时粘贴会多插一枚短名芯片)不改反解析,改为把不变量前移到引用名:
|
||||
|
||||
- `resourceReferences.ts` 新增共享 `normalizeMentionName(value)`(内部空白折 `-`、裁首尾),素材显示名(`resourceDisplayName`)、Skill 名(目录读入与 `toReference` / `mentionToken`)、附件名(导入映射与 `toReference` / `mentionToken`)与两个 token 投影(`chatReferenceMentionToken`、`directCodexContentToPromptText`)统一过这一份;token 层重复归一化是幂等的。
|
||||
- 名称里不做 `resourceId` 兜底这一条按评审校正:词干为空(`.env` / `.gitignore` 这类整名就是扩展名的文件)时 `resourceDisplayName` 回退 `asset.id`,回退值同样过 `normalizeMentionName`;`normalizeMentionName` 自己仍只做归一化。
|
||||
- 代价与取舍:`hero v2` 与 `hero-v2` 归一化后同名时走既有的「同名多候选按文本保留」;改动前生成的旧文本里的 `@hero v2` 不再解析。
|
||||
- 验证:`normalizeMentionName` / 显示名 / token 口径单测 + 前缀重叠回归用例(归一化后粘贴只剩正确的那一枚芯片)+ provider 两处用例;把 `normalizeMentionName` 变异成恒等后新增用例全红。
|
||||
|
||||
## 追加执行状态(2026-09-23 第二轮自动评审):空名字与插入兜底收口
|
||||
|
||||
第二轮自动评审的四个问题逐个提交处理,落点都在 `apps/ai-game-creator-shell`:
|
||||
|
||||
- 显示名不再可能为空:`resourceDisplayName` 在文件名词干为空(`.env` / `.gitignore`)时回退 `asset.id`,回退值同样过 `normalizeMentionName`(提交 `4e90465c4`)。这条校正了上一节「不做兜底」的写法,决策记录与功能说明同步。
|
||||
- 粘贴解析跳过退化 token:`buildContentFromPastedText` 组装候选时跳过 `token.length <= 1` 的条目,裸 `@` / `$` 不再认领正文里的触发符(提交 `3f9c698a6`)。
|
||||
- 粘贴接管改成「插入真的发生之后」才 `preventDefault`:`$insertContentAtSelection` 返回「插进去没有」,插入为空时放行默认粘贴;编辑器已在更新中(回调被排队)时按原口径先接管(提交 `3391ecf7d`)。
|
||||
- 插入兜底不再留空:provider 的 `toReference` 与 `mentionToken` 都答不出来的 part 退到新增的 `contentPartText`(通用文本形态,资源落 `@resourceId`)。此前这一支会什么都不插,是「粘贴内容逐字保留」唯一的例外分支;现在没有例外。新增单测覆盖四类 part 的文本形态,新增输入区集成用例证明被破坏的 provider 契约下这段粘贴仍按文本落下,去掉兜底即变红。
|
||||
- 归一化撞名(`hero v2` 与 `hero-v2` 折成同一个 token)只在解析侧兜住、候选菜单不提示冲突,这一条涉及「哪些素材能被 @ 到」的产品取舍,未改代码,留给下一轮决定。
|
||||
- 润色回写与粘贴共用同一条落点兜底:新增 `mentionTokenOrText`(provider 的 `mentionToken`,拿不到就退 `contentPartText` 的通用文本形态),润色回写的候选扫描、整根替换的落点与粘贴插入的兜底都走它。由此润色回写不再有「provider 答不出 token 的 part 直接消失」和「整根替换时 part 解析不出引用就整条吃掉」两条静默丢弃路径;初始草稿(`applyContent`)与润色回写(`applyPolishedTextToRoot`)共用 `applyContentToRoot`,所以恢复出来的草稿里已解析不出的引用现在落成 `@resourceId` 文本而不是被吃掉。
|
||||
@@ -121,6 +121,12 @@
|
||||
|
||||
- 发布灰度改为**默认关闭**并修掉客户端“看得到点不动”:`is_game_distribution_publish_enabled_for_user` 现在要求 gate 行存在且 `enabled=true`(未登录、无行、`enabled=false` 一律 false),因此没配灰度时 `gameDistributionPublishEnabled=false`,AGC 不再渲染「发布到游戏广场」按钮、网页入口也不出现;AGC 侧新增 `announcePublishMessage`,把「已构建并打包试玩包」「先打开一个项目再发布」等提示通过 DirectProject 聊天容器的 `announce` 出口回话(普通项目不渲染工作台状态行,之前只写 workspaceStatus 才会表现为点击无反应)。后台「灰度发布配置」新增「可配置开关」列表:预设开关在未创建行时也可见并可一键配置(不再需要先猜 gate key)。
|
||||
|
||||
## 2026-09-23 口径更新:发行入口改为服务端派生
|
||||
|
||||
- 管理员不再填写 `entryUrl`:审核通过时 `api-server` 读版本取 gameId,按部署模板 `GENARRATIVE_GAME_DISTRIBUTION_RELEASE_ENTRY_TEMPLATE`(生产形如 `https://{gameId}.games.<发行域名>/`,必须含 `{gameId}` 占位符)派生每游戏独立来源地址,再走原有 HTTPS / 无凭据 / 无 query / 无 fragment 校验;后台审核 DTO 与页面已删除该输入框。
|
||||
- 上文「已完成证据」中描述「管理员填写 / 要求 HTTPS 发行入口」的条目是当时的交付事实,当前口径以主规范《平台入口与玩法链路》《本地开发验证与生产运维》与 `shared-memory/decision-log.md` 的 2026-09-23 条目为准。
|
||||
- 非生产环境未配置模板时仍回落到本地发行网关回环地址(用于免 TLS 验证内嵌游玩);生产未配置模板、模板缺 `{gameId}`、gameId 非主机安全字符或派生结果非法时,审核通过直接失败。
|
||||
|
||||
## 尚未完成
|
||||
|
||||
- 真实独立发行域名、通配 TLS 与 CDN 仍属部署侧:边缘模板与门禁已就绪,本地已用真实 nginx 验证按主机映射、Cookie 403 与命名空间隔离,但仍需在真实域名/证书下跑一次“审核通过 → 游玩 → 换版 → 下架”并确认 CDN TTL 不超过 60 秒窗口。
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# 实施计划:游戏分发阶段 C · AGC 发布资料 AI 生成
|
||||
|
||||
- 状态:`in_progress`
|
||||
- 日期:`2026-09-23`
|
||||
- 上游:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` 的“AGC 游戏分发与在线游玩合同”
|
||||
- 里程碑:`docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md` 阶段 C
|
||||
|
||||
## 1. 交付结果
|
||||
|
||||
AGC 发布面板完成三项收敛:
|
||||
|
||||
1. 移除 ZIP 路径、文件数、体积和“只上传字节”等技术摘要。
|
||||
2. 打开面板时基于有界、脱敏的项目上下文免费生成一句话简介和七类白名单分类;失败保留本地兜底,不阻断发布,生成结果可编辑。
|
||||
3. 游戏封面支持基于项目上下文生成,复用现役图片生成与泥点扣费链路;生成结果登记为当前账号平台素材后自动作为 `coverAssetId`,不二次上传。
|
||||
|
||||
## 2. 实现边界
|
||||
|
||||
- 只改 AGC 发布面板、AGC 发布 service、api-server 内部发布资料建议路由、shared DTO、定向测试和文档。
|
||||
- 不改网页发布表单、游戏分发审核 API、发行包上传/审核状态机、SpacetimeDB schema 或 `/api/external/v1` OpenAPI。
|
||||
- 简介/分类生成不写用户泥点账本;封面生成继续由现役 `execute_billable_asset_operation_with_cost` 负责预扣、幂等、失败退款和结果登记。
|
||||
- 传给文本模型的上下文只包含项目名称、创作目标、任务标题/状态、素材 kind/相对路径、运行状态和最近编辑提示;不包含绝对路径、聊天记录、凭据、Token 或完整 manifest。
|
||||
|
||||
## 3. 实现步骤
|
||||
|
||||
1. `packages/shared` 与 `shared-contracts` 增加发布资料建议请求/响应 DTO,分类继续使用 `GAME_DISTRIBUTION_CATEGORIES`。
|
||||
2. api-server 增加 `POST /api/game-distribution/publish-metadata/suggestions`,经 Bearer 鉴权后使用内部文本模型生成严格 JSON;解析失败或模型不可用时返回本地确定性兜底,不触发钱包扣费。
|
||||
3. AGC `GameDistributionPublishPanel` 打开时调用建议接口;用户未修改字段时回填,用户已编辑或迟到响应不得覆盖,失败不影响发布。
|
||||
4. AGC 封面生成复用 `POST /api/editor/images/generations` 的 `publication-material`、`gpt-image-2`、`16:9`、`2K` 合同;按钮和确认弹窗从 `/api/editor/generation-pricing` 读取并显示具体泥点数。若响应进入队列,轮询 `/api/runtime/external-generation/jobs/{operationId}`,完成后直接使用 `assetObjectId`。
|
||||
5. 发布截图同批并行上传;成功缩略图悬浮显示“删除|预览”,失败缩略图内部显示错误并在下方保留删除按钮。失败项不参与发布,不阻断同批其它截图。
|
||||
6. 定向测试覆盖面板删除技术摘要、免费资料回填、封面价格/确认/生成/`coverAssetId` 直用、截图并行与单张失败跳过、服务端 parser/route 与输入边界。
|
||||
|
||||
## 4. 验收判据
|
||||
|
||||
- 发布面板不出现 `发行包摘要`、ZIP 相对路径或文件数/体积。
|
||||
- 建议接口成功时简介和分类自动回填;分类只可能是七类之一;接口失败时保留原创作目标或通用兜底。
|
||||
- 建议请求不会调用钱包、不会写 `asset_operation_consume` 或 LLM Router 额度账本。
|
||||
- 封面按钮和确认弹窗显示后端运行时定价对应的具体泥点数;确认后调用现役图片生成接口,生成结果直接成为发布 `coverAssetId`,没有第二次上传或素材身份分叉。
|
||||
- 同批截图并行上传;成功图悬浮显示删除/预览,失败图内部显示错误并有独立删除按钮;失败项不参与发布且不影响其它截图。
|
||||
- 生成失败、余额不足和队列失败均在面板内可见且可重试,不进入聊天历史。
|
||||
- 定向 vitest、api-server Rust 测试、AGC typecheck、`check:encoding`、`git diff --check` 通过。
|
||||
|
||||
## 5. 非目标
|
||||
|
||||
- 不做标题 AI 改写。
|
||||
- 不做网页发布页的自动生成。
|
||||
- 不新增发布草稿持久化、生成历史、重试队列或 SpacetimeDB 表。
|
||||
- 不改变封面上传入口和手动选择封面的能力。
|
||||
|
||||
## 6. 本次缺陷修复记录
|
||||
|
||||
- 2026-09-23:AGC 生成游戏封面请求补充 `generationInputs.source = "ai-game-creator-client"`。队列 worker 依据该来源选择 `GameCreatorResourceEditor` 结果契约;未标记来源时会按 `Standard` 紧凑化并省略 `result`,导致生成完成后无法回传 `assetObjectId`。对应前端定向测试已锁定请求字段与平台素材 ID 回填链路。
|
||||
@@ -1,92 +0,0 @@
|
||||
# 【实施计划】退役策划 Agent V1/V2 解耦清理
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】退役策划Agent V1V2解耦清理-2026-09-15.md` |
|
||||
| Status | ready |
|
||||
| Owner | Codex |
|
||||
|
||||
## 一句话交付结果
|
||||
|
||||
删除退役策划 V1/V2 及其耦合的 Supervisor 产品残留,让当前 Design Agent 独立运行、做游戏走 DirectCodex 并恢复仓库编译;保留通用 Supervisor 和做游戏 16 Agent DAG。
|
||||
|
||||
## 验收判据
|
||||
|
||||
当前分支能够通过 AGC 前端 typecheck 和受影响定向测试;Design Agent 的新建、恢复、澄清、阶段审批和 reasoning 展示仍由当前 Design Agent 链路完成;旧 V2 IPC、旧 GDD 类型和旧前端测试契约不再存在。
|
||||
|
||||
## 修改边界
|
||||
|
||||
允许修改:
|
||||
|
||||
- `apps/ai-game-creator-shell/src/App.tsx` 中旧 V2 状态、helper、IPC 分支和旧 UI props。
|
||||
- `apps/ai-game-creator-shell/src/app/types.ts` 中旧 GDD 类型。
|
||||
- `apps/ai-game-creator-shell/src/features/project-workspace/planningSessionV2.ts` 及其直接调用方。
|
||||
- `apps/ai-game-creator-shell/tests/appSurface/harness.ts`、`home.suite.ts`、旧策划事件测试。
|
||||
- `apps/ai-game-creator-shell/src/styles.css` 中只属于旧 Plan GDD / planning lane 的样式。
|
||||
- 没有现役调用方的旧策划身份 fixture、注释和文档索引。
|
||||
- 为通过编译所需的最小共享残留删除或改名。
|
||||
|
||||
明确不修改:
|
||||
|
||||
- `directCodex` 主链路和当前 Design Agent。
|
||||
- 16 Agent DAG、`supervisor-swarm` 测试和通用 Runtime 编排;只处理删除策划耦合后直接造成的编译错误。
|
||||
- 当前 Design Agent Rust runtime、Design Agent 资源包和 Design Agent IPC 协议。
|
||||
- 公开 API、SpacetimeDB schema、迁移和历史持久化数据格式。
|
||||
|
||||
## 实现顺序与提交拆分
|
||||
|
||||
### 提交一:解耦 Design Agent 状态命名
|
||||
|
||||
- 将新版 Design Agent 实际使用的 `planningV2*` transient reply、reasoning、active ref 和相关 lane 控制改成 Design Agent 专属状态。
|
||||
- 保持行为不变,不删除旧 V2 会话代码。
|
||||
- 验证:AGC typecheck、`git diff --check`。
|
||||
|
||||
### 提交二:删除 App 旧 V2 会话控制流
|
||||
|
||||
- 删除仅服务旧策划的 Supervisor 产品入口、恢复、轮询和聊天提交分支。
|
||||
- 删除旧 V2 session/GDD 状态和 helper。
|
||||
- 删除项目打开、消息发送、问询回答、审批和旧流式事件分支。
|
||||
- 将“做方案”只连接到当前 Design Agent hydrate/continue/decide 路径,将“做游戏/做素材”只连接到 DirectCodex。
|
||||
- 保留 `planningStartMode` 作为入口路由字段,避免无关扩大重命名。
|
||||
- 验证:AGC typecheck;必要时运行 App 启动相关定向 suite。
|
||||
|
||||
### 提交三:删除旧 TypeScript 适配层和类型
|
||||
|
||||
- 删除 `planningSessionV2.ts`。
|
||||
- 删除 `PlanGddDecisionAction`、`PlanGddStateViewV1` 及所有直接导入。
|
||||
- 重新执行旧符号检索,确认没有残留调用方。
|
||||
- 验证:AGC typecheck、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
### 提交四:清理测试、事件契约和 CSS
|
||||
|
||||
- 精确删除 harness 中旧 V2/GDD 工厂、mock、调用记录和导出。
|
||||
- 精确删除首页 suite 中旧 V2 IPC 断言。
|
||||
- 删除旧 `planning-session-v2-stream` 事件测试。
|
||||
- 删除 Plan GDD、GDD 审批卡和 planning lane 专属 CSS 及过时说明。
|
||||
- 验证:appSurface 定向测试、事件订阅定向测试、AGC typecheck、编码和 diff 检查。
|
||||
|
||||
### 提交五:收口确定失效的身份残留和文档入口
|
||||
|
||||
- 只处理因 V1/V2 退役而确定失效的旧身份展示、测试 fixture、注释和文档索引。
|
||||
- 不扫描或重构做游戏 DAG;共享代码只在其旧策划用途已确定死且删除能直接解决编译/测试问题时处理。
|
||||
- 验证:旧策划符号定向检索、相关测试、编码和 diff 检查。
|
||||
|
||||
## 验证命令
|
||||
|
||||
1. `npm --prefix apps/ai-game-creator-shell run typecheck`
|
||||
2. `npm run check:encoding`
|
||||
3. `git diff --check`
|
||||
4. `npm --prefix apps/ai-game-creator-shell exec vitest run tests/appSurface.test.ts`
|
||||
5. 受影响 Rust 文件变化后运行 `cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml`
|
||||
6. 完成全部提交后再次执行旧策划符号检索,并核对 `git status` 与提交边界
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- 最大风险是新版 Design Agent 复用了旧变量名;必须先完成提交一,再删除旧 helper。
|
||||
- `ProjectSupervisorView` 已经移除旧 GDD props,App 传参残留会在提交二中一并删除。
|
||||
- 测试 harness 同时服务通用总控和 Design Agent,必须局部删除旧 mock,不能整段重写。
|
||||
- 若某次提交导致 Design Agent 测试失败,只回滚该独立提交,不恢复旧 V2 兼容层。
|
||||
|
||||
## 完成后的临时文档处理
|
||||
|
||||
全部里程碑验收通过后,删除本里程碑和实施计划两份临时文档;把仍然有效的长期边界同步回现行 Design Agent 技术方案和项目记忆,不保留阶段性提交步骤。
|
||||
@@ -1,21 +0,0 @@
|
||||
# 关联里程碑
|
||||
|
||||
`【里程碑】退役策划V2 Rust Runtime清理-2026-09-14.md`
|
||||
|
||||
# 修改顺序
|
||||
|
||||
1. 从 `runtime_protocol.rs` 移除 V2 模块声明与导出。
|
||||
2. 从 `main.rs` / `commands.rs` 移除 V2 command 注册和仅供 V2 的导入。
|
||||
3. 删除 V2 Rust 模块及其专属单元测试;保留共享 GDD 模型或新版设计会话仍使用的类型。
|
||||
4. 用 `rg` 检查 V2 Rust 符号残留,修复编译引用。
|
||||
|
||||
# 验证命令
|
||||
|
||||
- `cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml`
|
||||
- `npm run check:encoding`
|
||||
- `git diff --check`
|
||||
|
||||
# 风险与回滚
|
||||
|
||||
- 风险:V2 类型可能被共享测试或前端桥接代码引用。处理方式是按编译错误逐项判断,保留真正共享类型。
|
||||
- 回滚:按提交粒度回退本里程碑提交,不触碰前序 V1 清理提交。
|
||||
@@ -0,0 +1,58 @@
|
||||
# AGC 发行包分片续传上传
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | runtime-smoke-passed(真实栈「中断 → 续传 → 确认」已通过;AGC 真机一键发布与 200 MiB 档容量数据未验证) |
|
||||
| Date | 2026-09-23 |
|
||||
| Parent Spec | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`(真实发行包与资料合同第 10 条、幂等并发与恢复) |
|
||||
|
||||
## 背景与触发
|
||||
|
||||
AGC 一键发布今天把整包字节从 WebView 侧送出:`read_local_project_export_package` 先把 `packageBytes` 整包过一遍 IPC 回到渲染进程,渲染进程再用 `@tauri-apps/plugin-http` 发整包 `PUT`,而该插件会把 body 序列化成 `Array.from(new Uint8Array(buffer))` 再走一次 IPC。两次整包 IPC 决定了 AGC 实际可发布的包远小于服务端 200 MiB 上限,失败时表现为客户端侧传输错误(例如「无法连接登录服务」),服务端访问日志里没有这次请求;断流后也只能整包白传。本里程碑把上传下沉到原生侧并支持分片续传。
|
||||
|
||||
## 目标
|
||||
|
||||
1. AGC 一键发布由原生进程直接读取本地试玩包、按服务端下发的固定分片大小上传,整包字节不再经过 WebView IPC。
|
||||
2. 传输中断、网络失败、客户端进程退出或应用重启后,同一 `versionId` 只补传缺失字节,不白传整包。
|
||||
3. 分片入口与现役整包 `PUT` 共用同一版本状态机、摘要口径、幂等键与包校验;网页端发布路径不变。
|
||||
|
||||
## 不在本里程碑内
|
||||
|
||||
- 不改网页端发布路径(继续整包 `PUT`),不为浏览器实现续传。
|
||||
- 不做并行分片上传、不做客户端直传 OSS(分片仍经 `api-server` 转发,与今天整包路径同一出口)。
|
||||
- 不做「后台自动续传」:续传只在下一次发布动作或应用重启后的重试里发生,不引入常驻重传任务。
|
||||
- 不做未完成分片会话的定时清理任务;半包对象的回收单独开里程碑。
|
||||
- 不改发行包上限、展开量、单文件与文件数上限。
|
||||
|
||||
## 合同要点
|
||||
|
||||
- **入口与状态**:分片续传对既有 `versionId` 生效,版本状态沿用 `awaiting_upload → uploaded → …`;分片入口与整包入口互斥,同一版本同时只能有一个写入者,第二个写入返回 `409 UPLOAD_IN_PROGRESS`。
|
||||
- **权威偏移**:服务端记录的已收字节是唯一权威。客户端分片偏移与之不符时返回 `409` 与权威偏移,客户端按权威偏移续传;重复分片不得造成重复写入。
|
||||
- **完成动作**:全部字节到齐后才执行校验与确认;校验失败删除半包对象并把版本落到 `upload_failed`(`recoveryAction=reupload`)。重新上传同一版本前必须显式重置分片会话,重置后偏移归零,不允许在半包之上续写不同字节。
|
||||
- **可见性**:半包对象不进入公开目录、不服务发行网关、不改变当前公开版本;与既有「未通过审核不改变 `activeVersionId`」口径一致。
|
||||
- **原生侧边界**:原生上传只读本地试玩包并逐片发送,进度以事件回传渲染进程;渲染进程不再持有整包字节。
|
||||
|
||||
## 依赖
|
||||
|
||||
- `platform-oss`:需要一组可续写的对象写入原语(追加语义或等价的分片会话),以及读取已收字节的探测能力;现役只有整对象 `PUT`。
|
||||
- `api-server`:`modules/game_distribution.rs` 新增分片入口与完成动作,复用既有 `validate_release_zip`、OSS 上传重试分类、`package_confirmed` / `package_rejected` 可观测事件。
|
||||
- AGC:`src-tauri` 新增原生上传命令与进度事件,`src/services/gameDistributionPublish.ts` 改为调用原生命令;`read_local_project_export_package` 不再为发布回传整包字节。
|
||||
- 反代/网关:分片请求体远小于现役 210 MiB 放行量,沿用现有配置,不改限额。
|
||||
|
||||
## 验收标准
|
||||
|
||||
1. **不再整包过 IPC**:发布 200 MiB 档包时,渲染进程侧不出现整包字节(对照 `read_local_project_export_package` 的返回体与 IPC 报文大小),上传由原生进程完成。
|
||||
2. **续传生效**:上传中途断开传输后重发同一版本,只补传缺失分片;分片请求数、已传字节与最终包摘要三项均可复核。
|
||||
3. **跨重启续传**:上传中断时退出应用并重启,重新发布时服务端返回权威已收字节,客户端从该偏移继续,最终确认成功。
|
||||
4. **偏移与重复**:分片偏移不符返回 `409` 与权威偏移;重复提交同一分片不产生重复写入;同版本第二个写入者返回 `409 UPLOAD_IN_PROGRESS`。
|
||||
5. **失败关闭**:完成动作里校验失败(非法 ZIP、超限、压缩比越界等)删除半包对象、版本落 `upload_failed`,半包不出现在公开目录,也不影响当前公开版本。
|
||||
6. **兼容与回归**:整包 `PUT` 路径与既有测试保持绿;`npm run check:doc-index`、`npm run check:encoding`、`git diff --check` 通过;`check:spacetime-schema` 按是否新增持久字段决定是否纳入。
|
||||
7. **运行时证据(已获得)**:本地 api-server(`127.0.0.1:8082`,库 `genarrative-game-creator-dev`)+ 真实 OSS bucket 上跑通 `gameDistributionPublishLive.test.ts`:9.0 MiB 发行包跨 8 MiB 分片边界,第一片只发送一次,中断后续传从权威偏移 `8388608` 继续、第二片 `received_bytes=9437818`,最后 `package_confirmed`(`oss_put_skipped=true`);整轮 3.9s。**未获得**:AGC 真机(Tauri 运行时)一键发布的端到端运行,以及 200 MiB 档的耗时 / 内存容量数据。
|
||||
|
||||
## 待评审的决策点
|
||||
|
||||
1. **续写原语**:OSS 追加写(顺序、单对象、续传只需回读当前长度)对比 OSS Multipart(可并行、更通用但需要多组新操作)。建议追加写,顺序续传已满足本里程碑目标。
|
||||
2. **分片大小**:建议 8 MiB(200 MiB 上限 → 最多 25 片,单片请求体远低于现役放行量)。
|
||||
3. **重置语义**:建议只有显式重置(作者点「重新上传」或 `reupload` 恢复动作)才删除半包并归零;其余情况一律按权威偏移续传。
|
||||
4. **半包回收**:本里程碑只标记未完成会话,不做定时清理;回收另立里程碑(涉及「不得删除仍被公开版本引用的对象」口径)。
|
||||
@@ -42,7 +42,7 @@ AGC 项目开发对话的显示与恢复只依赖两项输入:**项目对话
|
||||
- 未知 item 类型由 Rust 原样透传(只有类型与身份,Rust 侧留 TODO),当前由前端投影丢弃。
|
||||
- 前端聊天卡片的工具形状是 `Omit<GameCreatorDirectToolCall, 'turnId'>`;`tool-calls.jsonl` 的持久化形状与 DirectRuntime 的写入保持不变。
|
||||
- 「可显示」的判据取**前端回合反馈**:一次翻页操作连拉到「合并后聊天投影的回合数增加」为止。工具卡片与思考文本虽然能通过 `projectDirectThreadItem`,但可能整页落进已渲染回合的折叠「执行过程」,不构成用户可见反馈;口径只在 `directHistoryPaging.ts` 里实现一份,首屏与「显示更早」共用。
|
||||
- 首屏切片的**新端边界**只认 `subscribe` 回执里的 `lastCompletedItemId`(含该条):回执到达之前不读首屏,也不退化成「取文件尾」;锚点缺失(订阅不可用 / 失败 / 历史为空)时才按文件尾取尾屏,`/history` 手动重读保持按当前文件尾取尾屏的恢复语义。
|
||||
- 首屏切片的**新端边界**只认 `subscribe` 回执里的 `lastCompletedItemId`(含该条):回执到达之前不读首屏,也不退化成「取文件尾」;锚点缺失(订阅不可用 / 失败 / 历史为空)时才按文件尾取尾屏,手动重读保持按当前文件尾取尾屏的恢复语义。
|
||||
|
||||
## 依赖与前置条件
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
|
||||
## 阶段 C:双端发布与现代游戏体验
|
||||
|
||||
- AGC 发布资料生成切片实施计划:`docs/project-memory/plans/【实施计划】游戏分发阶段C-AGC发布资料AI生成-2026-09-23.md`。
|
||||
|
||||
### 前置条件
|
||||
|
||||
- B 已验收;网页根入口、桌面/移动导航、暖色主题交互稿及首版设备范围已评审。
|
||||
@@ -94,6 +96,8 @@
|
||||
### 行为与验收
|
||||
|
||||
- [ ] AGC 从已构建 dist 生成根入口为 `index.html` 的真实包,一次提交动作完成检查、资料确认、上传和送审;状态及失败原因与服务端回读一致。
|
||||
- [ ] AGC 发布面板隐藏发行包技术摘要;打开时基于有界、脱敏的项目上下文免费生成一句话简介与白名单分类,失败保留本地兜底且不阻断发布;作者始终可以直接编辑生成结果。
|
||||
- [ ] AGC 发布封面支持基于项目上下文生成,复用现役图片生成与泥点扣费链路;生成结果登记为当前账号平台素材后自动作为 `coverAssetId`,不二次上传。
|
||||
- [ ] 网页可选 ZIP、提交封面和必需资料,进入相同上传/校验/审核流程;任一客户端可以查看同账号游戏状态,更新沿用相同 `gameId`。
|
||||
- [ ] 上传中断、双击、登录失效、窗口关闭后恢复原操作;换账号不能恢复前账号私有状态;待审不能显示为已发布。
|
||||
- [ ] 目录支持真实数据、关键词/分类/设备筛选、空/错/加载态;详情提供明确主动作,搜索与返回恢复上下文。
|
||||
@@ -103,7 +107,7 @@
|
||||
|
||||
### 证据要求
|
||||
|
||||
- 自动化:AGC 打包与操作恢复定向 Rust 测试、两端客户端/组件/路由/状态测试及类型检查。
|
||||
- 自动化:AGC 打包与操作恢复定向 Rust 测试、两端客户端/组件/路由/状态测试及类型检查;发布资料免费生成必须验证不写入钱包账本,封面生成必须验证扣费幂等、失败退款与 `assetObjectId` 直用。
|
||||
- 运行时:AGC 一次真实发布、网页一次真实 ZIP 上传,分别审核后从桌面和手机游玩;浏览器覆盖游戏模块、素材、音频、触屏及横竖屏。
|
||||
- 边界:未构建/失效 dist、资料缺失、换账号、迟到响应、审核拒绝、非移动游戏及真实空态。
|
||||
|
||||
@@ -116,7 +120,7 @@
|
||||
### 行为与验收
|
||||
|
||||
- [ ] 真实环境中完整跑通“首次上传 → 校验 → 审核 → 公开 → 游客游玩 → 更新待审旧版在线 → 新版切换 → 下架撤销”。
|
||||
- [ ] 100 MiB 包与获批文件数/展开量边界有可复核耗时、内存和失败证据;校验不会执行上传代码,服务资源有界。
|
||||
- [ ] 200 MiB 包(现行上限,见 2026-09-23 决策记录)与获批文件数/展开量边界有可复核耗时、内存和失败证据;校验不会执行上传代码,服务资源有界。已有证据覆盖 100 MiB 档,上限提升后的档位待复跑。
|
||||
- [ ] 校验执行器重启可恢复,审核积压与失败可观测,清理不删除仍被公开版本引用的文件。
|
||||
- [ ] CDN purge 失败时仍在获批缓存 TTL 内拒绝新资源;明确已下载脚本无法远程抹除的边界。
|
||||
- [ ] 发布/回滚步骤保留当前公开版本,能关闭新提交和新版本激活;部署路由、缓存、响应头、日志脱敏和告警完成检查。
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
# 【里程碑】退役AGC项目对话斜杠命令与终端swarm chat入口-2026-09-22
|
||||
|
||||
状态:已完成
|
||||
父规范:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
|
||||
|
||||
## 目标与判据
|
||||
|
||||
一句话目标:AGC 应用内不再存在任何斜杠命令语义,终端 swarm chat CLI 入口(`--swarm-chat`)连同其命令层整体退役,且不再残留只服务这两者的实现、测试、文案与构建期门禁;行为上等同于它们从未存在。
|
||||
|
||||
验收判据:
|
||||
- AGC 应用内(`apps/ai-game-creator-shell/src/**`)除路径/路由字面量外,不存在形如 `'/xxx'` 的命令字面量,也不存在对 `/` 开头输入的命令分支。
|
||||
- 斜杠命令专属模块与其导出全部消失,`projectSummary` 桶文件只保留现役导出。
|
||||
- 权威文档不再承诺「聊天输入 `/<cmd>`」能力,终端章节点也不再把控制命令列为入口。
|
||||
- 终端侧不再存在 swarm chat 入口与其命令层;`--agent-run`、`--agent-enqueue`、`--agent-steer`、`--agent-resume`、`--agent-context-compact`、`--preview-serve` 等运维类控制命令保持现役。
|
||||
- 依赖终端入口的真实 E2E 与脚本(`user-input`、`supervisor-autonomous-playable-lane-defense`、三个 supervisor-swarm 混合套件、`agc:test`、`agc:test:chat*`、`agc:chat`、`agc:swarm`)与交互式 CLI harness 管道一并消失。
|
||||
- 不新增任何守卫测试或 check 脚本条目。
|
||||
|
||||
## 范围
|
||||
|
||||
范围内(删除):
|
||||
- `features/project-summary/projectSummaryConstants.ts` 的 `chatCommandHelp` 与全部命令清单常量。
|
||||
- `features/project-summary/chatCommandMetadata.ts`(斜杠命令参数校验文案)。
|
||||
- Direct 聊天的 `/history` 精确匹配分支与 `reloadHistory`。
|
||||
- `chatPromptPolish` 的 `/` 前缀绕过分支。
|
||||
- `memoryCommands.ts` 的 `parseRememberInput`(`/remember` 参数解析器)。
|
||||
- 只服务退役 Supervisor 摘要面板、零外部调用的 `project-summary/*Summaries.ts` 与 `agentTrace.ts`。
|
||||
- `/sync-canvas-project`、`/read <path>`、`/trace` 的草稿回填死链(前端 `agentPresentation.ts` + Rust `suggested_canvas_tool_call`)。
|
||||
- 无人调用的 Tauri 命令 `get_game_creation_agent_capabilities`、`get_limited_local_commands`。
|
||||
- 钉住上述字符串的构建期门禁条目与专属测试。
|
||||
- 终端 swarm chat 入口与整个命令层:`cli.rs` 的 `SwarmChat` 变体、`--swarm-chat` 解析与派发、`src/swarm_cli.rs` 与 `src/swarm_cli/` 整个目录(输入解析与帮助输出、`/agents`、`/status` 打印器、`/goal` 引擎、`/compact`、`/resume`、`/quit` 退出分支、观察器、报告、turn 派发与等待)、`SwarmChatFlow`、`SwarmTurnObservation`、`SwarmTurnOutcome::Quit`、`SwarmConfirmationResolution::Quit`、`SWARM_TURN_*_ERROR`,以及 `swarm_cli/input.rs` 中那份只为终端命令存在的 `agent.compact` / `agent.resume` / `agent.run_status` 权限校验(同名权限 id 在现役 Tauri 命令与 Runtime 生命周期上的门禁保持不动)。
|
||||
- 只服务终端交互内核的 `agent/interaction.rs` 整层:`AgentInteractionAction`、tool registry、`game_creator_agent_uses_interaction_kernel`、`decide_game_creator_agent_interaction_turn_for_session_at`、`AgentInteractionProviderStreamSink`;其上的自然语言 steer 决策 LLM 路径 `decide_game_creator_agent_runtime_steer_at` 在收尾复查后一并删除,见「收尾清理」。
|
||||
- 只能由命令触达的打印器:`print_runtime_response_stream_status` 及其专属测试。
|
||||
- 依赖终端入口的脚本与套件:`scripts/agent-swarm-test-chat.mjs`、`scripts/agent-runtime-deterministic-playable-e2e.mjs`、`scripts/deterministic-lane-defense-provider.mjs`,套件 `user-input`、`supervisor-autonomous-playable-lane-defense`、`supervisor-swarm-autonomous-chat`、`supervisor-swarm-static-isolated-autonomous-chat`、`supervisor-swarm-collaboration-policy-mixed-recovery`,以及 harness 里的交互式 CLI 管道(`startInteractiveCli`、`writeInteractiveCliLine`、`waitForInteractiveCli*`、`closeInteractiveCli`、`activeInteractiveCliSessions`、`answerRemainingInteractiveQuestions` 等)与只服务这些套件的混合套件分支、状态字段、sentinel 与 npm 脚本。 同时清掉只被这些套件调用的 harness 残件:`collaboration-assertions.mjs` 的混合/静态隔离断言族(`supervisorSwarmMixed*`、`observeSupervisorSwarmStaticIsolatedProviderOverlap`)、`repair-recovery.mjs` 的静态隔离观测调用点、evidence 模板与校验里的 `mixed*` / `staticIsolated*` / `initialBatchRecovery*` 占位字段,以及 `self-test.mjs` 中对应的合成用例与汇总字段。
|
||||
|
||||
范围外(保留):
|
||||
- 命令 id 注册表 `GAME_CREATION_APP_COMMANDS` 与 `GameCreationAppPermission`(项目权限策略词汇表;App 前端只用 `GameCreationAppCommandDescriptor` 类型表达权限判定与审计粒度,数组本体由 Rust 策略路径消费)。
|
||||
- `needsInitializedChatProject` 与项目权限策略链路。
|
||||
- Rust 侧路径/路由的 `/` 前缀校验。
|
||||
- `--agent-run`、`--agent-enqueue`、`--agent-task`、`--agent-steer`、`--agent-retry`、`--agent-cancel`、`--agent-confirm`、`--agent-resume`、`--agent-runtime-status`、`--agent-goal-*`、`--agent-context-compact`、`--runner-status`、`--runner-shutdown-if-idle`、`--llm-status`、`--preview-serve`、`--environment-check`、`--direct-codex-chat` 等运维与开发 CLI 控制命令。
|
||||
- 保留的真实 E2E 套件:`supervisor-swarm`、`supervisor-swarm-transient-retry`、`supervisor-swarm-final-reply-transient-retry`、`supervisor-swarm-tool-plan-handoff-runner-kill`、`goal-runtime`、`response-stream`、`web-search`、`context-compaction`、`scoped-agents`、`project-skill`、`parallel-read`、`steer-runner-kill`、`process-session`。
|
||||
|
||||
## 检查点
|
||||
|
||||
1. 斜杠语义层:Direct `/history`、润色绕过、`chatCommandHelp`/`chatCommandMetadata`、`parseRememberInput`、桶文件与门禁、专属测试。
|
||||
2. 死链与死模块:草稿回填链(前端 + Rust + 断言)、零调用摘要模块、`agentTrace.ts`。
|
||||
3. 无人调用的能力清单 Tauri 命令。
|
||||
4. 文档收口:AGC 主专题命令承诺、ADR、`decision-log.md`、`CONTEXT.md`。
|
||||
5. 终端 swarm chat 命令层与只服务它的权限门禁、打印器、专属测试。
|
||||
6. 终端 swarm chat 入口本体、交互内核、`--swarm-chat` 派发与其专属 Rust 测试。
|
||||
7. 依赖终端入口的 e2e 套件、deterministic wrapper/provider、npm 脚本、构建期门禁条目、harness 交互式 CLI 管道、混合套件分支,以及随之失效的混合/静态隔离断言族与 evidence 占位字段。
|
||||
8. 文档收口:终端入口退役后主实施计划、Runtime 文档、ADR、decision-log、pitfalls、里程碑计划的最终口径。
|
||||
|
||||
## 验证
|
||||
|
||||
- `npm run --workspace apps/ai-game-creator-shell typecheck`(含 `skill-pack:check` 与 `check-config.mjs`):通过。
|
||||
- 定向用例 `npx vitest run tests/appSurface.test.ts`:211 tests(202 passed / 9 skipped);`chatPromptPolish`、`rememberCommand`、`ChatMarkdownMessage`、`agentRuntimeModel` 等相关用例集通过。
|
||||
- `cargo check --tests`:0 error;删改文件无新增 `dead_code` 告警(按「父提交 vs 本次」引用数逐条比对告警标识符确认)。
|
||||
- `npm run check:encoding`、`npm run check:doc-index`、`git diff --check`:通过。
|
||||
- 真实 E2E harness 自检 `node scripts/agent-runtime-real-e2e.mjs --self-test`:`status: PASS`;harness 相对与具名 import 全部可解析。
|
||||
- 收尾清理(2026-09-23,LLM steer 判定链):`cargo check --tests` 0 error,告警与改动前基线一致(无新增 `dead_code`);`npm --workspace apps/ai-game-creator-shell run typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check` 通过;幂等复核 `steer_decision` / `interrupt_for_steer_decision` / `decide_game_creator_agent_runtime_steer_at` 在 `apps/`、`packages/` 源码中零命中。
|
||||
|
||||
## 文档收口
|
||||
|
||||
- `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`:删除全部「聊天输入 `/<cmd>`」能力条目,保留并改写其中的非命令事实;`/compact`、`/mcp`、`/goal`、`/resume` 的终端承诺改为对应 `--agent-*` 入口。
|
||||
- `docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`:删除终端 swarm chat 入口整节,控制面统一记为 `--agent-*` CLI(`/goal` → `--agent-goal-*`、`/compact` → `--agent-context-compact`、`/mcp` → 开发配置面板与真实 E2E 核验);终端不再承担任何交互式聊天职责。
|
||||
- `docs/adr/【ADR】退役AGC项目对话斜杠命令与终端swarm chat入口-2026-09-22.md`:本次决策与影响边界。
|
||||
- `docs/project-memory/shared-memory/decision-log.md`:新增 2026-09-22 决策条目,并清理已被本次退役取代的历史命令条目。
|
||||
- `docs/project-memory/shared-memory/pitfalls.md`、`docs/project-memory/plans/【里程碑】DirectProject聊天真相源收敛-2026-09-16.md`:移除 `/history` 入口表述,改为「显式重新加载对话」。
|
||||
- `CONTEXT.md`:新增「项目对话输入」「项目命令 id」术语,把「斜杠命令」标为已退役说法;不再出现 `/history` 重读入口。
|
||||
- `docs/README.md`:登记新 ADR。
|
||||
|
||||
## 收尾清理
|
||||
|
||||
复查(2026-09-23)发现退役残留与随之产生的零引用代码,按同一口径清理:
|
||||
|
||||
- 配置向导 `scripts/game-creator-config-wizard.mjs`:删除指向已删脚本的 `npm run test:chat` 调用、失去含义的 `--configure-only` 开关,以及只服务该分支的 `askYesNo` 与 `npmCommand`。
|
||||
- 用户文案:App 内 `请先用 /project 设置本地项目。` 改为 `请先打开本地项目。`。
|
||||
- 注释与 prompt:`chatPromptPolish` 头部注释的 `/` 命令表述、`harness/process.mjs` 与 `scripts/check-config.mjs` 中指向已退役入口的说明,以及 `interaction.json` 中只服务已删交互内核的 7 个键(`execute_description`、`resume_description`、`project_location_description`、`protocol`、`system`、`user`、`user_with_context`)。
|
||||
- harness 死导出:`runtime-state.mjs` 的 4 个 schema 常量、`assertions/runtime.mjs`、`harness/project.mjs`、`collaboration-policy.mjs`、`persistence.mjs` 中因调用方被删而零引用的函数,连同因此失去用途的 import。
|
||||
- 无前端调用方的 Tauri 命令 `start_game_creator_agent_runtime_task` 与 `steer_game_creator_agent_runtime_task` 全部删除(`main.rs` 注册与 `check-config.mjs` 条目同步移除)。删掉 steer 命令后其唯一非测试入口的整条 LLM steer 判定链一并退役:`agent/interaction.rs`(`runtime_steer_decision` 工具、判定请求构建、响应解析、`decide_game_creator_agent_runtime_steer_at`)、`runtime.interrupt_for_steer_decision` RPC 与派发分支、持久 decision 记录(`agent.runtime.steer_decision`)、`AgentRuntimeProviderInterrupt::applied_steer_cursor`、`AgentRuntimeSteerResult` 的 `assistantReply / interruptDecision / decisionReason` 字段、`steer_decision_*` prompt 键,以及只测该链条的 provider / runner / runtime_state 用例。
|
||||
|
||||
## 未做与边界
|
||||
|
||||
- 不为退役概念新增守卫测试或断言残留字符串的 check 条目。
|
||||
- 不为终端入口与已删套件补充替代实现、兼容别名或迁移提示。
|
||||
@@ -1,49 +0,0 @@
|
||||
# 【里程碑】退役策划 Agent V1/V2 解耦清理
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | proposed |
|
||||
| Date | 2026-09-15 |
|
||||
| Parent Spec | `docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md` |
|
||||
|
||||
## 目标
|
||||
|
||||
移除旧版策划 Agent V1、V2 的前端会话、审批、数据适配、测试契约和确定失效的展示残留;仅在删除策划链路时遇到已退役 Supervisor 功能耦合时一并删除该耦合,使“做方案”只使用当前 Design Agent、做游戏只使用 DirectCodex。
|
||||
|
||||
## 范围
|
||||
|
||||
- 解除当前 Design Agent 与旧 `planningV2` / `PlanGdd` 状态命名和控制流的耦合。
|
||||
- 删除仅服务旧策划的 Supervisor 产品入口、会话恢复、Runtime 轮询和聊天提交分支;保留通用 Supervisor 与做游戏 DAG。
|
||||
- 删除旧 V2 会话 hydrate、start、continue、审批和用户问询分支。
|
||||
- 删除旧 V2 TypeScript 会话适配层、旧 GDD 前端类型、测试 mock、旧事件契约和专属样式。
|
||||
- 清理确定没有现役调用方的旧策划身份说明、测试 fixture 和文档当前入口。
|
||||
- 保留当前 Design Agent 的会话、澄清、阶段审批、工作区浏览和 reasoning 展示行为。
|
||||
|
||||
## 不在范围内
|
||||
|
||||
- 不主动扫描、重构或整体删除做游戏 Agent 的 16 Agent DAG;只有策划删除直接造成编译或测试失败时才做最小修复。
|
||||
- 不删除 DirectCodex 或当前 Design Agent;必要时保留被两者复用的中性聊天表现组件。
|
||||
- 不为旧项目新增兼容层、迁移器、墓碑注释或退役行为测试。
|
||||
- 不修改 SpacetimeDB schema、公开 API、持久化迁移和现役 Design Agent 协议。
|
||||
|
||||
## 依赖与前置条件
|
||||
|
||||
- PR #159 的合并提交 `3d8e0211` 代表旧 Fast GDD / 策划 V1 的引入。
|
||||
- PR #305 的合并提交 `04128eb6` 同时包含 V1 大范围退役、策划 V2 会话链路和后续 Design Agent 迁移。
|
||||
- 当前分支已经删除 Rust V1/V2 Runtime 模块和旧审批组件,但前端仍残留旧 V2 调用方;实现前须保持工作树干净。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] “做方案”入口和已有 Design Agent 项目只调用当前 Design Agent IPC,不再调用旧 `planning_*_v2` IPC。
|
||||
- [ ] 当前 Design Agent 的消息、reasoning、澄清、阶段审批和重试行为不依赖旧 V2 状态变量。
|
||||
- [ ] 源码中不再存在旧 V2 TypeScript 会话适配层、旧 `PlanGdd` 类型和旧前端审批契约。
|
||||
- [ ] 旧前端测试、事件测试和样式残留被删除或改为当前 Design Agent 契约。
|
||||
- [ ] 不主动修改做游戏 Supervisor + 16 Agent DAG;因共享退役代码删除产生的编译错误得到最小修复。
|
||||
- [ ] 前端 typecheck、相关定向测试、编码检查和 diff 检查通过;触及 Rust 时对应 cargo check 通过。
|
||||
|
||||
## 证据要求
|
||||
|
||||
- 自动化:`npm --prefix apps/ai-game-creator-shell run typecheck`、相关 appSurface 定向测试、`npm run check:encoding`、`git diff --check`。
|
||||
- 运行时:至少验证“做方案”新项目进入 Design Agent、已有 Design Agent 会话恢复、澄清/审批回合可继续。
|
||||
- 边界:确认 DirectCodex 和做游戏既有入口未被旧策划清理改动;确认旧 V2 IPC 字符串和旧事件契约不再进入现役前端。
|
||||
@@ -1,38 +0,0 @@
|
||||
# Version
|
||||
|
||||
V2-RUST-RETIRE-1
|
||||
|
||||
# Status
|
||||
|
||||
in-progress
|
||||
|
||||
# Date
|
||||
|
||||
2026-09-14
|
||||
|
||||
# Parent Spec
|
||||
|
||||
`docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`
|
||||
|
||||
# 目标
|
||||
|
||||
删除已经被独立 Design Agent 取代的旧策划 V2 Rust Runtime、Tauri 命令注册和仅服务 V2 的模块导出,使桌面壳继续编译并保留做游戏 Agent 与新版 Design Agent。
|
||||
|
||||
# 边界
|
||||
|
||||
- 删除 `planning_policy_v2`、`planning_session_v2` 及仅供这两者使用的 V2 注册和调用。
|
||||
- 删除 V2 专属的 Tauri command 注册、模块导出和测试入口。
|
||||
- 保留 `design_runtime`、`design_tools`、`design_session`、通用 runtime、DirectProject 和做游戏 Agent。
|
||||
- 本里程碑不处理前端 V2 数据层、UI、文档索引和共享运行时中的可选清理。
|
||||
|
||||
# 验收标准
|
||||
|
||||
1. Rust 源码不再编译 `planning_policy_v2.rs` 或 `planning_session_v2.rs`。
|
||||
2. `main.rs`、`commands.rs` 和 runtime protocol 不再注册或导出 V2 命令。
|
||||
3. 新版 Design Agent 与做游戏 Agent 的 Rust 编译路径保持可用。
|
||||
4. 相关定向 Rust 测试和 `cargo check` 通过。
|
||||
|
||||
# 依赖
|
||||
|
||||
- 当前分支已包含 PR159 的 V1 清理。
|
||||
- 前端 V2 调用暂时保留,待后续里程碑同步删除。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,6 +53,8 @@
|
||||
|
||||
## 验证路由
|
||||
|
||||
Windows 下的移动壳 smoke 通过 Node 启动从当前 workspace 包解析出的 Expo/EAS CLI,不直接 `spawnSync('npm.cmd')`;保留原配置与导出断言。具体入口和警告清理边界见本地开发运维文档。
|
||||
|
||||
提示词外置变更运行 `runtime_prompt_bundle_build` 与 `prompt_source_boundaries` 两个 Rust 集成测试,验证编译期文本、目录登记和源码边界;现有 `agc-rust-shard-1` 本地/CI 入口先执行这组检查,再运行分片单测。
|
||||
|
||||
提示词测试验证实际请求中的片段来源、动态参数和工具结构;措辞不作为逐字契约。已有行为测试覆盖的限制不再另设整段文案检查。Direct 回合测试复用生产的消息转换和文件投影函数,不维护仅供测试调用的回合编排副本。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 文档地图与阅读索引
|
||||
|
||||
更新时间:`2026-08-31`
|
||||
更新时间:`2026-09-23`
|
||||
|
||||
## 阅读顺序
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
AI 游戏创作 / DirectProject / UI workflow:
|
||||
|
||||
1. `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
|
||||
2. `docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`(历史方案,仅供追溯)
|
||||
2. `docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md`(当前 Design Agent;旧策划 V1/V2 均已退役)
|
||||
3. `docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md`
|
||||
4. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`
|
||||
5. `docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`(历史 V1 方案,仅供追溯)
|
||||
6. `docs/technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md`
|
||||
7. `docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md`
|
||||
8. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`
|
||||
9. `docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`
|
||||
10. `docs/technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md`
|
||||
11. `docs/technical/【技术方案】Direct回合行为审计账本-2026-08-31.md`
|
||||
9. `docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`(历史 V2 方案,仅供追溯,不是当前实现依据)
|
||||
10. DirectProject 附件按 AGC 主实施计划的 canonical `userItem` 合同;`docs/technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md` 为旧 sidecar 历史方案,不作为实现入口。
|
||||
11. Direct 历史、审计与耗时按 AGC 实施计划及原始历史专题;`docs/technical/【技术方案】Direct回合行为审计账本-2026-08-31.md` 已归历史,不作为实现入口。
|
||||
12. `docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md`
|
||||
13. `docs/【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md`
|
||||
14. UI 编辑器、宿主壳和当前测试专题文档
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
# 踩坑与排障记录
|
||||
|
||||
> 策划历史条目边界:旧策划 V1/V2 已全部退役,当前入口仅使用 Design Agent。下文带日期的旧 Planning V2、Fast GDD、`plan.submit_gdd`、旧 IPC/模块记录仅用于追溯,不能作为恢复旧代码、身份门禁或专属测试的依据;共享问题需在现役调用上核查。现行合同见[策划 Agent 生产迁移与工作区浏览](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。
|
||||
|
||||
## 2026-09-24 对话过程卡的读秒退回 1 秒一跳:刷新粒度必须与显示精度同格
|
||||
|
||||
- **现象**:AGC DirectProject 对话区底部那条「陶泥儿正在处理 / 已耗时 12.4秒」的状态条,小数位一秒才动一格,看着像读数卡住;同一屏里工具卡片的耗时与资源生成侧栏的读秒都在正常走 0.1 秒,只有这一处不动。
|
||||
- **原因**:耗时文案不足一分钟保留一位小数(`formatElapsedDuration`),刷新就必须是 100ms。这次改动方向本身是对的——把 clock 从整个聊天视图下移到耗时那一行,但顺手在组件里另写了一份 `setInterval(..., 1000)`,绕过了对话侧唯一的 `useLiveNow`(`LIVE_TIMER_TICK_MS = 100`);`team-conventions.md` 里「运行时用 100ms 叶子时钟刷新一位小数、终态冻结」这条约定当时已经写好,改动没有对齐它。
|
||||
- **处理(现行口径)**:耗时文案的刷新一律走 `useLiveNow`,不在视图组件里另起 interval;tick 只订在显示耗时的那一行(叶子节点),不能落在整块面板或整份回合列表上。可机检的判据是「不足一分钟的耗时必须每 100ms 递增一次小数位」。
|
||||
- **验证**:`npx vitest run apps/ai-game-creator-shell/tests/directProjectProcessStatus.test.tsx`(把 `LIVE_TIMER_TICK_MS` 临时改回 1000 时第一步即红);真实浏览器里 600ms 内文案从 `18.0秒` 走到 `18.6秒`。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectConversation/DirectProjectConversation.tsx`、`apps/ai-game-creator-shell/src/features/project-workspace/useLiveNow.ts`、`apps/ai-game-creator-shell/src/styles.css`。
|
||||
|
||||
## 策划回复的重复终态不能重新启动伪流式
|
||||
|
||||
策划 Runtime 会通过状态事件与命令返回交付同一份最终视图。若前端清空临时正文后再拿“最后一条非用户历史消息”回填动画,就会出现正式回复旁又播放一遍、播放后消失的假重试。正文应按 `messageId` 保存显示进度,与正式消息共用一个气泡;请求完成不清动画,不延迟正式业务状态。Provider 自动重试复用消息 ID 并发送空文本,只允许重置未持久化的该条回复。正文、工具状态和 reasoning 分开;事件与异步命令收尾均检查项目及活动回合,旧请求不能覆盖新回合。详见 [AGC 实施计划](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)。
|
||||
|
||||
## 2026-09-23 弹窗打开时自绘标题栏的最小化 / 最大化 / 关闭静默失效
|
||||
|
||||
- **现象**:AGC 打开「发布到游戏广场」面板(以及其它任何弹窗)后,右上角三个窗口按钮点了没有任何反应,拖拽标题栏也不能移动窗口;关掉弹窗立刻恢复。标题栏看着完全正常,遮罩也明显只压住了下面的工作区,所以很容易误判成「按钮自己坏了」或 Tauri 窗口 API 挂了。
|
||||
- **原因**:标题栏在模态之外,但它是窗口边框。`ThemedModal` 用的 `focus-trap-react` 在 **document 捕获阶段**监听 `mousedown`/`touchstart`/`click`:模态外的点击一律 `preventDefault()`,`click` 还会 `stopImmediatePropagation()`。React 的监听挂在 document 内的根容器上,捕获阶段就被掐掉的 `click` 永远到不了 React,于是既不报错也不执行 —— 与「焦点陷阱吞掉模态外点击」是同一类问题(见 2026-09-20 发布面板焦点陷阱那条)。另有一条独立的同类缺陷:`.app-update-overlay` 用 `inset: 0`,把标题栏真的盖住了,更新弹窗期间按钮被遮罩挡住。
|
||||
- **处理(现行口径)**:① 全屏弹层一律从标题栏下方开始(`top: var(--window-chrome-height)`),不得用 `inset: 0` 盖住标题栏;② `ThemedModal` 的焦点陷阱用 `allowOutsideClick` 只放行落在 `[data-window-chrome-bar]` 内的目标,工作区内容点击继续被拦;③ 新增全屏弹层时把类名补进 `apps/ai-game-creator-shell/tests/windowChromeOverlayContract.test.ts` 的清单。
|
||||
- **验证**:`npx vitest run apps/ai-game-creator-shell/tests/themedModal.test.tsx apps/ai-game-creator-shell/tests/WindowChrome.test.tsx apps/ai-game-creator-shell/tests/windowChromeOverlayContract.test.ts`(标题栏点击放行、工作区点击仍被拦、7 个全屏弹层都在标题栏下方);两个新增用例去掉修复后确实失败,确认能守住这条约定。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/components/modal/ThemedModal.tsx`、`apps/ai-game-creator-shell/src/components/WindowChrome.tsx`、`apps/ai-game-creator-shell/src/styles.css`。
|
||||
|
||||
## Direct 宿主继续请求不能重发原始用户条目
|
||||
|
||||
原始 `direct_user_item` 同时参与历史持久化和模型输入转换;验收或错误反馈更新了 prompt 后,如果发送层仍优先转换原始条目,模型会收到重复的用户输入,而本地历史按 itemId 去重后只显示一次。首次请求与宿主继续必须显式区分:首次保留结构化输入,继续发送当次反馈,原始条目只保留历史与事件关联职责。GUI、CLI 的两条循环都要覆盖;只改反馈文本或清空原始条目不完整。见 [Direct 宿主继续请求输入修复](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md#2026-09-23-direct-宿主继续请求输入修复)。
|
||||
|
||||
## 最近项目一次失败会被钉成终态
|
||||
|
||||
- **现象**:AGC 卡住一次后,项目列表每一行都显示「检查失败 + 待识别」,首页「最近项目」变成「暂无最近项目」;现场在后端恢复后逐条复跑 `inspect_local_project_directory`(8 个项目)全部 0ms 成功,界面仍然全红(issue #490)。
|
||||
- **原因**:单次检查的 5s 超时被吞成 `null` 写入状态表,而刷新用的增量投影是 `next[path] = current[path] ?? null`,把失败结果原样搬进下一轮;effect 只依赖列表与刷新计数器,既没有重试也没有 focus/visibility 重查。于是一次抖动会让整张列表永久停在失败态,首页同时被 `canOpen` 过滤清空。
|
||||
- **处理**:失败就地重试一次(300ms);失败结果不进新投影;一轮仍有可重试失败时按 15s / 45s / 120s 重跑整表(上限 3 次,失败集合变化即重置预算)。提权/权限类失败(`DACL`、`权限`、`error 5`、`安全对象不属于当前用户`、`特权`、`1300`、`AGC ACL 提权修复未成功`)按不可重试处理,在用户主动打开/新建项目或重命名刷新之前跳过——否则「提权被拒 → 300ms 后重试」会自己驱动 UAC 反复弹窗。
|
||||
- **验证**:`apps/ai-game-creator-shell/tests/recentProjectsHook.test.tsx` 的三条用例(「单次失败就地重试」「失败不跨轮保留」「提权类失败不重试」),改前代码上前两条必挂;`tests/appSurface/home.suite.ts` 的失败态断言改为等待最终状态。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/features/app-shell/useRecentProjects.ts`、`src-tauri/src/config.rs`。
|
||||
|
||||
## 策划 Agent 提示词中的相对路径不要当作内部实现删去
|
||||
|
||||
`project/...` 是 Agent 读写策划工作区的目标路径,`resources/...` 是查找内置分册、模板和例子的资源定位;即使阶段上下文也注入了同一产物路径,提示词里的路径仍是 Agent 需要的契约。清理宿主实现细节时不要误删这些相对路径,具体用法见[策划 Agent 路径说明](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md#6-阶段与提示词注入)。
|
||||
|
||||
## AGC 素材直传的 OSS 权限必须同步到 Native shell 契约检查
|
||||
|
||||
- **现象**:Native shell CI 在 `check:native-shells:contract` 的 HTTP scope 检查失败,尚未准备 Rust 缓存;后续导出步骤正常退出但实际跳过,导致 master 缓存产物缺组、自动镜像刷新等待。
|
||||
@@ -825,6 +863,7 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- 并发边界:steer 入队、Runner `runtime.steer` 通知都不得直接触发 Provider interrupt。Codex app-server 的判定使用独立节点,不能等待主节点 turn 锁;判定为 true 后也只能中断 `appliedSteerCursor < steer.sequence` 的旧 Provider 请求,已经消费该 steer 后启动的新请求不可被误杀。已经开始的工具和外部动作不强杀,完成 observation 后再消费 steer。
|
||||
- 验证:真实 mock LLM 回归必须覆盖状态询问回复且 `interruptCurrentProvider=false`;持久重放只保留一条语义回复;steer 入队后旧 Provider 继续运行,判定为 true 后才中断;新规划 Provider 的 cursor 已包含该 steer 时即使旧判定为 true 也不能中断。前端同秒多条消息保持“用户补充 → 判断提示/语义回复”的关联顺序。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/interaction.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/steering.rs`、`apps/ai-game-creator-shell/src-tauri/src/runner/dispatch.rs`、`apps/ai-game-creator-shell/src/features/agent-runtime/model.ts`。
|
||||
- 2026-09-23 更新:`agent/interaction.rs` 与 `steer-decision` LLM 判定链已整体删除,本条中「判定 LLM / `interruptCurrentProvider` / 只中断旧 cursor」的实现细节仅作历史记录;现役语义是 steer durable 入队后由 `runtime.steer` 唤醒,并在下一安全边界应用。
|
||||
|
||||
## Jenkins 异步备份不能用 nohup 脱离作业
|
||||
|
||||
@@ -4431,9 +4470,9 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
|
||||
- 现象:`npm run agc:test:chat` 在进入聊天前报“Agent Runner 版本与当前客户端不一致,但旧 Runner 仍有任务,暂不能重启”;正式客户端仍能看到自己的待确认或委派任务,重复执行测试也持续失败。
|
||||
- 原因:Runner 复用身份同时绑定协议版本和当前可执行文件 SHA-256。`cargo run` 重新编译后的 debug 二进制与正在运行的 release Runner 指纹不同,而旧入口只隔离测试项目、仍把正式 AppData 直接传给 CLI,于是测试会向正式 endpoint 发升级探测。正式 Runner 有 pending action、Provider sidecar、进程会话或非终态队列时拒绝退出是正确的安全门禁,不能通过强退或放宽 idle 判定让测试通过。
|
||||
- 处理:正式 AppData 只作只读配置来源。每次人工测试在系统临时根创建 `0700` sentinel 隔离目录,只把主配置和可选 local overlay 私有复制为 `0600` 普通文件;不得复制 endpoint、lock、`.previous` 或其它状态。LLM 检查与 Swarm CLI 全部使用隔离目录。退出时通过内部 CLI 请求 `runner.shutdown_if_idle`,确认隔离 endpoint 消失后才删除配置;仍有任务或无法确认退出时同时保留测试项目和隔离配置并报告路径。正式 Runner 的 PID、bootId、端口和 executable fingerprint 必须保持不变。
|
||||
- 处理:正式 AppData 只作只读配置来源。每次人工测试在系统临时根创建 `0700` sentinel 隔离目录,只把主配置和可选 local overlay 私有复制为 `0600` 普通文件;不得复制 endpoint、lock、`.previous` 或其它状态。LLM 检查与端到端测试入口全部使用隔离目录。退出时通过内部 CLI 请求 `runner.shutdown_if_idle`,确认隔离 endpoint 消失后才删除配置;仍有任务或无法确认退出时同时保留测试项目和隔离配置并报告路径。正式 Runner 的 PID、bootId、端口和 executable fingerprint 必须保持不变。
|
||||
- 验证:单元测试覆盖私有 inode、权限、local overlay、禁止复制 endpoint/lock/备份、符号链接拒绝、sentinel 清理和 endpoint 存在时拒绝删除;真实 smoke 使用隔离 AppData 启动并收束空闲 Runner,前后比较正式 endpoint 身份且确认正式 PID 存活,再检查本轮 `/tmp` 项目和隔离配置均已清理。
|
||||
- 关联:`apps/ai-game-creator-shell/scripts/agent-swarm-test-chat.mjs`、`apps/ai-game-creator-shell/tests/agentSwarmTestEntry.test.ts`、`apps/ai-game-creator-shell/src-tauri/src/runner/client.rs`、`apps/ai-game-creator-shell/src-tauri/src/cli.rs`。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/runner/client.rs`、`apps/ai-game-creator-shell/src-tauri/src/cli.rs`。
|
||||
|
||||
## Swarm 队列 busy 不能直接当成 canonical run 可 steer
|
||||
|
||||
@@ -4441,7 +4480,7 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- 原因:旧 `runtime_is_busy` 同时包含当前 state 和队列汇总,调用方看到 `task_queue.pending > 0` 后仍从 canonical state 反推 steer、失败扫描和 turn report 的 runId;取消 tombstone 还会让恢复扫描在处理 A 后无条件跳过 B。底层拒绝 terminal steer 和保留 A 的真实失败历史都是正确行为,不能通过放宽门禁或删除历史记录修复。
|
||||
- 处理:保留 queue busy 用于 Runner 存活判断,另由 Runtime 协议层提供唯一 steerable 判定。start mutation 返回实际 `acceptedRunId`,CLI 以它建立不可变 turn baseline;失败、reconciliation、用户交互、收束和报告只观察该 run。canonical 已推进到后续 run 时从 task journal 读取目标 run 的最终记录。旧 cancelled canonical 若仍有 pending 且无 running,恢复扫描跳过旧 run 的 pending action 恢复,直接启动队首 pending。若输入与已落盘 pending task 及最后一条 user 消息相同,则只观察原 run。Goal 路径也必须核对同一 Agent、Session、runId、Run Profile 和 steerable 状态。连续 run 的回复必须按确定性 finalization message ID 过滤;历史 specialist 失败必须以 `(agentId, runId)` 为键读取完整 journal,不能让滞后的非失败 state 删除 journal 已记录的失败;报告计数也不能退回 `recent_tasks` 的 12 条窗口。
|
||||
- 验证:构造 cancelled run A、保留 A cancel tombstone、pending run B 和单份已落盘用户消息,证明恢复后 B 进入 running 并完成且 conversation 不重复。另覆盖观察 B 时忽略 A 及 A 子任务失败、观察 A 时仍正常失败、B 完成后 canonical 已推进到 C 仍可从 journal 收束 B、`turn.report.parentRunId` 始终为 baseline,以及 expected Goal runId 不一致时不选中目标。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/swarm_cli/turn_dispatch.rs`、`apps/ai-game-creator-shell/src-tauri/src/swarm_cli/terminal_classification.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/steering.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/recovery_scan.rs`。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/steering.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/recovery_scan.rs`。
|
||||
|
||||
## 2026-07-25 autonomous-game-build 不能只检查 game/index.html 就宣称正式项目完成
|
||||
|
||||
@@ -4456,9 +4495,9 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
|
||||
## 终端真实测试不能混用配置参数、stdin EOF 和持续预览
|
||||
|
||||
- 现象:开发者第一次运行 `agc:test:chat` 时必须先打开 GUI 才能配置 Provider;无 TTY 的脚本可能在 stdin 立即 EOF 后零任务成功退出,或者任务已经完成却继续等待 preview 的 `Ctrl+C`,导致自动化看似卡死。若为图省事增加 `--api-key`,密钥还会进入 shell history 和进程列表。
|
||||
- 现象:开发者第一次运行真实 E2E 聊天测试时必须先打开 GUI 才能配置 Provider;无 TTY 的脚本可能在 stdin 立即 EOF 后零任务成功退出,或者任务已经完成却继续等待 preview 的 `Ctrl+C`,导致自动化看似卡死。若为图省事增加 `--api-key`,密钥还会进入 shell history 和进程列表。
|
||||
- 原因:把首次配置、手工多轮聊天、单轮真实测试和持续试玩当成同一个交互生命周期;同时让 GUI 与 CLI 使用不同配置入口,或把 EOF 既解释为“提交当前需求”又解释为“没有输入”,会让退出语义随调用环境漂移。
|
||||
- 处理:GUI 与 `npm run agc:config` 共用系统 AppData `game-creator.config.json`,终端隐藏输入 API Key 并禁止 `--api-key`;更新时保留 `agentLlm`、`editorApi`、`mcpServers` 等其它配置,POSIX 权限维持目录 `0700` / 文件 `0600` 并原子替换。显式 `--config-dir` 必须以 `world.genarrative.ai-game-creator` 为独立叶目录,不能让向导对 `/tmp`、AppData 根或共享目录整体 chmod / 重建 DACL。隐藏输入调用 `stdin.resume()` 后必须记住原 pause 状态,在成功、取消、异常和 `SIGINT / SIGTERM / SIGHUP` 路径恢复 raw mode 并 `pause()`,信号恢复后重发;只移除 `data` listener 会让 `--configure-only`、配置检查失败或 Ctrl+C 保持活动 stdin。缺配置时仅 TTY 人工会话可询问进入向导,非 TTY 立即失败并提示配置命令。
|
||||
- 处理:GUI 与 `npm run agc:config` 共用系统 AppData `game-creator.config.json`,终端隐藏输入 API Key 并禁止 `--api-key`;更新时保留 `agentLlm`、`editorApi`、`mcpServers` 等其它配置,POSIX 权限维持目录 `0700` / 文件 `0600` 并原子替换。显式 `--config-dir` 必须以 `world.genarrative.ai-game-creator` 为独立叶目录,不能让向导对 `/tmp`、AppData 根或共享目录整体 chmod / 重建 DACL。隐藏输入调用 `stdin.resume()` 后必须记住原 pause 状态,在成功、取消、异常和 `SIGINT / SIGTERM / SIGHUP` 路径恢复 raw mode 并 `pause()`,信号恢复后重发;只移除 `data` listener 会让 配置检查失败或 Ctrl+C 保持活动 stdin。缺配置时仅 TTY 人工会话可询问进入向导,非 TTY 立即失败并提示配置命令。
|
||||
- Windows 密钥复制:`mode: 0o600` 和 POSIX `chmod` 在 Windows 上不能代替 DACL。隔离 AppData 目录必须先设置仅当前用户、禁止继承的 DACL;目标配置文件先以空文件创建并收紧 DACL,之后才允许把 API Key 字节写入。先 `copyFile` 再依赖 Rust 只读检查或事后收紧会留下密钥暴露窗口,也可能因继承 ACL 不满足 Runtime 合同而在首次 `--llm-status` 失败。
|
||||
- Windows PowerShell 参数:不要把 DACL 目标路径和目录标记直接追加在 `powershell.exe -Command <script>` 后;Windows Node `spawn` 会让 PowerShell 5.1 把这些值拼入命令文本,带空格的临时路径会被拆分并使 `GetFullPath($args[0])` 失败。当前实现只通过子进程私有环境变量传入路径和布尔值,并由真实 Windows `npm run agc:typecheck` 覆盖 DACL 回归。
|
||||
- 测试超时补充:配置向导的读路径和写路径都会加固私有目录与配置文件,`readGameCreatorWizardConfigState` 与 `writeGameCreatorConfigAtomically` 只要没拿到 `secureWindowsPath` 桩,Windows 上每次调用就各自拉起真实 `powershell.exe`(本机实测约 `0.6s` / 次)。只给写路径传桩、漏掉读路径时,单条用例会累计 `9` 次加固、耗时约 `5.5s`,稳定撞上 vitest 默认 `5000ms` 上限并报 `Test timed out in 5000ms`(不是断言失败)。凡只校验配置分层优先级、不校验 ACL 的用例,读写路径必须带上同一份 `skippedWindowsAclOptions` 桩,把用例耗时从秒级压回 `24ms` 量级;确实要覆盖私有 ACL 的用例才保留真实加固,并自行留足超时预算。隔离 Swarm 运行配置的入口 `prepareSwarmTestRuntimeConfig` 按同一范式暴露了可选第三参 `{ secureWindowsPath }`,默认 `null` 时仍走真实实现,生产调用点保持单参调用;一次调用在双配置文件场景最多加固 3 次,不传桩时同样会稳定吃掉秒级预算。
|
||||
@@ -4516,7 +4555,7 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
|
||||
## tool-plan handoff 不能把计划叙述和源码字段当成配置载荷扫描
|
||||
|
||||
- 现象:Provider 已返回 HTTP 200 并计费,tool-plan lifecycle 却只有 `started`,handoff 账本停在上一 loop,Runtime 进入 `needs-reconciliation`;重启 Runner 或 `/resume` 后仍原样被屏障阻断。
|
||||
- 现象:Provider 已返回 HTTP 200 并计费,tool-plan lifecycle 却只有 `started`,handoff 账本停在上一 loop,Runtime 进入 `needs-reconciliation`;重启 Runner 或运行显式恢复(`--agent-resume`)后仍原样被屏障阻断。
|
||||
- 原因:在解析 function arguments 之前,对整段 `response.text` 和序列化 arguments 统一执行 `.env`、`game-creator.config` 等字面标记扫描。安全叙述如“无需读取 `.env`”,或 `oldText / newText / content / patch` 中的普通源码字面量,会在真实路径和内容字段尚未区分时被误判。原始响应未成功交接时不会留下正文,因此现场只能结合 loop 边界和最小复现定位,不能把高概率分支冒充已恢复的原响应证据。
|
||||
- 处理:计划叙述与规范源码内容字段只检查真实密钥 token 形状、凭据头标记和不安全控制字符;结构化敏感 JSON key、非内容字段的配置痕迹和绝对路径、真实 token、容量、thinking、身份、顺序及账本完整性继续失败关闭。成功 handoff 失败时只在 Runtime event/state 和 Agent DB 保存受控 `failureKind`、脱敏错误 SHA-256、字符数与 requestId,禁止保存正文、arguments、密钥和绝对路径。
|
||||
- 验证:必须同时覆盖 narrative 和 `oldText / newText / content / html / patch` 提及 `.env` / `game-creator.config` 可 round-trip,`path=.env.local` 与 `sk-...` 真实 token 仍拒绝,全部 handoff 回归通过;诊断审计必须断言不存在 `error / response / arguments` 原文。修复后的外部 Provider 重试仍需新起独立轮次,不能与故障轮或确定性回归拼接为 PASS。
|
||||
@@ -4524,10 +4563,10 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
|
||||
## 自然语言“继续修复”不能在无活动 Runtime 时落入空 resume
|
||||
|
||||
- 现象:旧 run 已取消且 `/resume` 明确报告无可恢复任务,用户随后输入“继续”“继续之前干的事情”或“那就继续修复”,interaction 仍返回 `resume`,宿主反复扫描后不新建任务。
|
||||
- 原因:interaction 模型能看到会话历史,却不知道宿主已经排除了 active、pending 和可 steer Runtime;宿主又把自然语言 `resume` 与显式 `/resume` 当成相同控制动作机械执行。
|
||||
- 处理:活动 Runtime、排队任务和 Goal 仍在 interaction 前优先 steer/恢复;只有这些门禁全部为空后,自然语言 interaction 返回的 `resume` 才规范化为 `execute` 并创建新 run。显式 `/resume` 继续保持纯恢复控制,不因无任务而隐式执行。
|
||||
- 验证:保留自然语言必须进入统一 interaction loop 与显式 `/resume` 命令测试,并新增无活动 Runtime 时 `Resume -> Execute`、普通 reply 不变的回归。
|
||||
- 现象:旧 run 已取消且显式恢复入口明确报告无可恢复任务,用户随后输入“继续”“继续之前干的事情”或“那就继续修复”,interaction 仍返回 `resume`,宿主反复扫描后不新建任务。
|
||||
- 原因:interaction 模型能看到会话历史,却不知道宿主已经排除了 active、pending 和可 steer Runtime;宿主又把自然语言 `resume` 与显式恢复入口当成相同控制动作机械执行。
|
||||
- 处理:活动 Runtime、排队任务和 Goal 仍在 interaction 前优先 steer/恢复;只有这些门禁全部为空后,自然语言 interaction 返回的 `resume` 才规范化为 `execute` 并创建新 run。显式恢复入口(`--agent-resume`)继续保持纯恢复控制,不因无任务而隐式执行。
|
||||
- 验证:保留自然语言必须进入统一 interaction loop 与显式恢复入口测试,并新增无活动 Runtime 时 `Resume -> Execute`、普通 reply 不变的回归。
|
||||
|
||||
## tool-plan 中项目内绝对路径应在成功交接时规范化
|
||||
|
||||
@@ -5269,11 +5308,14 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
|
||||
- 现象:用户明确要求重做美术或切换游戏主题,工具仍立即返回 `assets/art-spec.png`、`assets/direct-game-background.png`、`assets/art-spritesheet.png`;新需求没有 Provider operation,游戏继续使用旧图。切片虽然已经落盘,也可能不出现在资源管理或工具结果中。
|
||||
- 原因:旧 Direct 工具只有 `brief`,完整包校验成功后无条件短路;固定阶段账本恢复又未比较本次生成 prompt。切片只写文件和切片清单,未作为顶层 manifest asset 投影;工具桥只返回三条主路径并丢失切片与 warning。
|
||||
- 处理:显式重做使用 `mode=regenerate`,普通请求使用 `reuse-or-create`。重生成必须由当前最新 User 消息明确授权并绑定客户端稳定 `clientTurnId`。授权先对完整原文做 Unicode NFKC 与撇号规范化,随后整串必须完整匹配审核过的独立立即执行指令,只允许句号/感叹号收尾;不得剥离引号、方括号或代码片段,动作前后也不得携带 brief、条件、否定、选择、确认、费用、延迟或其它文本。风格需求先单独描述,再由下一条独立“请重新生成美术”消息确认;不要靠扩充 deny 同义词推断付费同意。同一调用完成回包丢失只从 `completed` 持久结果等值重放,不能因重试再次扣费。App 必须在 Direct 调用前落盘原始 User 消息和回合 ID,Tauri 必须在成功返回前幂等落盘同 ID assistant 终态;同进程重复水合若命中“回合仍在运行”,只能显示瞬时占用提示,不得以稳定 assistant messageId 写成终态并抢占原执行的成功回复。恢复扫描与启动前置恢复必须发现 `resetting / compensating / anchored in-progress` 并在专用锁内恢复,重开项目只续跑真正未回答的原身份。整条付费链必须持有专用跨进程执行锁;换新回合时先持久化 `resetting` 再清理旧阶段账本,不得通过删除 workflow 留出无主窗口。崩溃补偿只恢复旧文件并清 replacement CAS 锚点,已 `prepared / accepted` 阶段账本、原 `Idempotency-Key / operationId` 必须保留,同冻结意图续跑复用旧请求;未知账本在文件 mutation 前失败关闭。只有没有任何阶段账本和替换锚点的孤立 workflow 空壳可原子接管;旧 schema 和其余冲突失败关闭。遇到 prompt 或当前 art-spec 身份不一致的未决账本必须保留原 operation 并返回对账错误。Direct app-server 可写边界只限真实 canonical `game/`,canonical 项目根的原生 OS 路径字节与权威 manifest `projectId` 经域标签和独立长度前缀编码后共同绑定连接池和 thread 身份,不得写项目根、`assets/`、`.agent/`,也不得获得网络、命令、MCP 或权限扩权;受控工具如果需要项目级客户端状态,只能从同一真实 `game/` cwd 经相同校验内部反查项目根,不能扩大模型可写根。标准图集首次创建和重生成都要求四张透明、可见、像素及平台身份唯一的 canonical 切片;工具只回传通过私有回执、公开清单、源图和顶层登记交叉验证的 `slicePaths` 与安全 `resources`。部分/opaque/重复/缺回执切片必须告警,不能把公开清单或顶层自述身份当作 Canvas 权威。
|
||||
- 处理:显式重做使用 `mode=regenerate`,普通请求使用 `reuse-or-create`。模式由 Codex 根据当前用户请求通过审核工具显式选择;客户端不再使用 Unicode NFKC、关键词、否定词表或独立确认句式判断业务意图。旧文本授权规则已被 2026-09-03 MCP 决策替代,相关无调用实现于 2026-09-23 删除。工具桥绑定活动客户端回合与稳定 `clientTurnId`,冻结首次 `brief` 摘要;缺少活动回合或摘要冲突仍拒绝。项目权限、账号、计费、幂等、锁与未知结果恢复合同继续有效。
|
||||
- 幂等与恢复:同一调用完成回包丢失只从 `completed` 持久结果等值重放,不能因重试再次扣费。App 必须在 Direct 调用前落盘原始 User 消息和回合 ID,Tauri 必须在成功返回前幂等落盘同 ID assistant 终态;同进程重复水合若命中“回合仍在运行”,只能显示瞬时占用提示,不得以稳定 assistant messageId 写成终态并抢占原执行的成功回复。恢复扫描与启动前置恢复必须发现 `resetting / compensating / anchored in-progress` 并在专用锁内恢复,重开项目只续跑真正未回答的原身份。整条付费链必须持有专用跨进程执行锁;换新回合时先持久化 `resetting` 再清理旧阶段账本,不得通过删除 workflow 留出无主窗口。崩溃补偿只恢复旧文件并清 replacement CAS 锚点,已 `prepared / accepted` 阶段账本、原 `Idempotency-Key / operationId` 必须保留,同冻结意图续跑复用旧请求;未知账本在文件 mutation 前失败关闭。只有没有任何阶段账本和替换锚点的孤立 workflow 空壳可原子接管;旧 schema 和其余冲突失败关闭。遇到 prompt 或当前 art-spec 身份不一致的未决账本必须保留原 operation 并返回对账错误。
|
||||
- 执行边界(2026-09-24 校准):DirectProject 的 cwd 与 AGC 业务身份根是用户选择的 canonical 项目根;其原生 OS 路径字节与权威 manifest `projectId` 经域标签和独立长度前缀编码后绑定连接池和 thread 身份。旧的 `game/` 唯一可写根、禁止全部网络 / 命令 / MCP 的描述已失效;也不能把后来的“完整访问”描述理解为绕过当前宿主门禁。当前 thread 使用 `sandbox=read-only`、`approvalPolicy=untrusted`,turn 使用 `sandboxPolicy.type=readOnly`;原生命令按逐次审批与宿主执行许可处理,客户端 MCP 仍校验项目绑定、业务权限和副作用许可。具体边界以[主实施计划“宿主验收与执行许可合同”](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md#宿主验收与执行许可合同)及当前实现为准,Provider 凭据保持隔离。
|
||||
- 资源投影:标准图集首次创建和重生成都要求四张透明、可见、像素及平台身份唯一的 canonical 切片;工具只回传通过私有回执、公开清单、源图和顶层登记交叉验证的 `slicePaths` 与安全 `resources`。部分/opaque/重复/缺回执切片必须告警,不能把公开清单或顶层自述身份当作 Canvas 权威。
|
||||
- 同进程恢复补充:命中“同一 stable turn 仍在运行”后除禁止写 assistant 终态外,还必须删除当前 App 实例的恢复 claim。这样原调用随后成功时显式刷新能读取其终态,随后失败时也能按相同 `clientTurnId` 再次续跑;不要靠重载 WebView 清理进程内 claim,也不要用无界定时轮询制造并发调用。
|
||||
- 严格图集崩溃补充:规范图和背景图的两文件 rollback 不覆盖严格图集事务已经整体修改的 `.agent/manifest.json`、私有回执、公开清单、主图集、四切片和切片清单。必须在严格调用前持久化 pending 及九项旧合同身份;重启恢复先对账底层严格事务,完整新合同直接收口完成,完整旧合同才补偿前两阶段,混合或漂移状态失败关闭。不要在严格提交成功后局部恢复前两张图。
|
||||
- 部分旧包补充:rollback 的规范图/背景图必须保存旧字节与旧 manifest entry,不能把这两项缺失隐式当成空内容;显式 `regenerate` 因此只在这两项可信可回滚时开放。历史主图集、私有回执、公开清单或 canonical 切片可以缺失,但八个严格路径与受管顶层 asset identity 必须逐项冻结其真实 `Present/Some` 或 `Missing/None` 状态,补偿也必须恢复相同存在性。不要因为旧美术包缺切片而阻断重生成,也不要把本轮新建的严格文件误记成旧文件。
|
||||
- 对话扫描与 claim 补充:历史中出现 `User A / User B / Assistant B` 时,B 已回答不代表 A 已回答,扫描必须继续寻找 A。成功 Direct 回复在 Rust 返回前已经落盘,前端冗余 append 失败不能据此重跑;普通错误回复的显式落盘失败时,恢复 claim 要保持到 React fallback writer 的同一 messageId append 明确收敛。writer 成功或明确失败后才释放;失败路径要停止该消息的自动迟到重试,再由显式 `/history` 复用原 stable turn。终态后及时删除 claim,避免 Set 无界增长。
|
||||
- 对话扫描与 claim 补充:历史中出现 `User A / User B / Assistant B` 时,B 已回答不代表 A 已回答,扫描必须继续寻找 A。成功 Direct 回复在 Rust 返回前已经落盘,前端冗余 append 失败不能据此重跑;普通错误回复的显式落盘失败时,恢复 claim 要保持到 React fallback writer 的同一 messageId append 明确收敛。writer 成功或明确失败后才释放;失败路径要停止该消息的自动迟到重试,再由显式重新加载对话复用原 stable turn。终态后及时删除 claim,避免 Set 无界增长。
|
||||
|
||||
## GDD 历史审批回执误触发当前恢复提示(2026-08-27)
|
||||
|
||||
@@ -5805,6 +5847,14 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- **处理(现行口径)**:① 产品行为保留“导出成功后自动打开面板”(一键发布入口),但受影响的用例必须先用 `findByRole('dialog', { name: '发布到游戏广场' })` 断言面板出现、点「关闭发布面板」再继续后续会话操作;② 给这类“新增自动弹窗”改流程时,先跑一遍相关 `appSurface` 用例,避免只跑新增用例;③ 排查同类“点了没反应”时,先看当前是否有焦点陷阱模态打开,而不是先怀疑事件绑定或状态。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/App.tsx`(`setPublishPanelOpen(true)`)、`apps/ai-game-creator-shell/src/components/modal/ThemedModal.tsx`、`apps/ai-game-creator-shell/src/components/game-distribution/GameDistributionPublishPanel.tsx`、`apps/ai-game-creator-shell/tests/appSurface/project-preview/preview-shortcuts/assert-project-tools-and-preview.ts`。
|
||||
|
||||
## 2026-09-23 AGC 发布按钮点了没反应:DirectProject 不渲染 workspaceStatus,权限确认也没有挂载点
|
||||
|
||||
- **现象**:AGC 聊天头能看到「发布」按钮,点击后没有任何提示、面板也不出现;项目权限要求确认时同样静默,用户只能描述为「点了没反应」。
|
||||
- **原因**:普通项目固定走 `DirectProjectChatView`,它不渲染工作台状态行,也不渲染 `PlanningChatView` 里那块 `pending-command` 确认卡片;发布提示、权限确认和取消结果原先只写 `workspaceStatus` / `messages`。上游 `f502829fd` 已把发布提示同时 `announce` 回 DirectProject,但确认卡片仍未挂载到 DirectProject;权限查询抛错也没有 catch,确认时策略改为拒绝同样只写工作台消息。结果等待确认、命令被拒、确认后拒绝这几条路径仍表现为「点了没反应」。
|
||||
- **处理(现行口径)**:发布相关提示统一走 `announcePublishMessage`,同时写 `workspaceStatus` 和 `directProjectChatRef.current.announce`;`DirectProjectChatView` 增加 `pendingConfirmation` / `onConfirmConfirmation` / `onCancelConfirmation`,在对话列表与输入盒之间渲染与 `PlanningChatView` 同形的确认条;`requestGamePublish` 对权限查询整段兜底并把错误回显到聊天,点击后先回「正在检查发布权限…」,进入导出再回「正在构建并打包试玩包」。
|
||||
- **验证**:`npx vitest run apps/ai-game-creator-shell/tests/gamePublishFeedback.test.tsx`(正常发布 / 导出失败 / 确认继续 / 取消 / 确认时拒绝 / 权限查询失败 6 条)与 AGC 全量前端用例通过;`npm run ai-game-creator-shell:typecheck`、`npm run check:encoding`、`git diff --check` 通过。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/App.tsx`、`apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx`、`apps/ai-game-creator-shell/tests/gamePublishFeedback.test.tsx`。
|
||||
|
||||
## 2026-09-21 受控 Lexical 输入区的回写用被动 effect:滞后渲染的 props 会把用户草稿清空
|
||||
|
||||
- **现象**:DirectProject 输入盒里粘贴(或连续输入)长文本,提交时 `chat_with_game_creator_direct_codex` 根本没发出去,界面停在空输入盒;`chat-composer` 用例里表现为「队列/终止/语音追加」五条一起红,但手工操作只在快速输入后偶发。
|
||||
@@ -5825,7 +5875,7 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
|
||||
- **现象**:`chat_with_game_creator_direct_codex` 的 Tauri 入参曾并列带一个 `prompt: String`(前端把 canonical content 渲染成 `@显示名` 文本),Rust 侧从不读取——`cargo check` 直接报 `src/agent/direct_runtime/user_input.rs` 的 `unused variable: prompt`;前端每次提交仍要算一遍,界面测试也钉着这份投影文本。
|
||||
- **成因**:DirectProject 回合真正的输入只来自 canonical `userItem`。`direct_codex_user_item_to_codex_turn_input`(`agent/direct_codex_user_item/wire.rs`)在 DirectProject 分支重建 `turn/start.input`,`LlmRunRequest` 里那份 `user_prompt` 会被覆盖;客户端投影走的是另一套口径(素材被删或改名时退化成裸 resourceId),一旦有人把它接回 Codex,就把 `@显示名` 标签污染了模型输入。
|
||||
- **现行口径**:IPC 只传 `projectPath`、`clientTurnId`、`userItem` 与可选 `creationType`;Rust 只从 `userItem` 派生回合输入(空判定与三维契约探测用的派生 prompt 仍在 Rust 内部生成)。前端那份 `@显示名` 投影只服务本地的 `/history` 识别与队列 chip 文案,不出 IPC;界面断言只能读 `userItem.content`。
|
||||
- **现行口径**:IPC 只传 `projectPath`、`clientTurnId`、`userItem` 与可选 `creationType`;Rust 只从 `userItem` 派生回合输入(空判定与三维契约探测用的派生 prompt 仍在 Rust 内部生成)。前端那份 `@显示名` 投影只服务本地的历史条目识别与队列 chip 文案,不出 IPC;界面断言只能读 `userItem.content`。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/user_input.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/direct_codex_user_item/wire.rs`、`apps/ai-game-creator-shell/src/view/project-development/chat/controller/useDirectProjectChatController.ts`、`apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts`。
|
||||
|
||||
## 2026-09-21 DirectProject 结构化消息不能逐个拒绝空白文本片段
|
||||
@@ -5862,3 +5912,51 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- CI 产物清理:Gitea 1.26.4 的仓库 REST 仅列出 finalized/expired V4 artifact,内置到期清理不回收上传中断的 tmp-upload 分块。缓存上传块须带专属标识,宿主只清理目标仓库已结束且超过 7 天的 master run 中同样过期的自有普通文件,未知文件/符号链接保护,不改数据库或全局 prune。Artifact.workflow_run 仅含 ID/SHA,判断过期产物所属事件和状态须再读 run API,不能当作完整 run 使用。
|
||||
- 自动切换:Gitea 1.26.4 的 disabled 检查与 FetchTask 事务不原子,Runner 客户端超时不能证明服务端回滚,容器暂时为空也不能证明没有已领取任务。网关必须解析实际 Connect Protobuf/gzip,转发 FetchTask 结果前持久化任务 ID,仅在最终日志及执行清理后的最终 UpdateTask 确认后清账;取消响应不能提前释放。暂停新领取、在途为零、账本为零且内层活动容器为空才可切换,无需全局 Runner admin API。未知协议/响应或崩溃遗留标记停止切换;旧网关缺 active_tasks 不能默认零。首次接入与账本升级须空闲窗口。.runner 的 mtime 不证明地址已加载,应核验真实 FetchTask 来源及本次容器启动时间。
|
||||
- 扩展:预热所有 Rust 测试组时保留各自 cwd、profile、features 和锁策略;同一临时 target 的 Cargo fresh 不代表不同 cwd 都已生成缓存键,AGC 提示词契约、分片和 smoke 切换入口前清理预热 target。不要把 workspace 与 spacetime-module 合并成一次编译;Native shell release step 清空双 wrapper,避免将测试缓存扩展成发布缓存。当前 sccache 0.18.0 的 READ_ONLY 在 miss 后仍打包产物并产生 cache write error,不适合用来承诺“未命中无开销”。
|
||||
|
||||
## 2026-09-22 卡片文字用 grid 的 auto 行排版,会被按「一行」裁掉
|
||||
|
||||
- **现象**:AGC 模板库卡片标题看着被切掉、简介只剩一行、标签行缺半截;`TEMPLATE_CARD_TEXT_HEIGHT` 与真实内容相差约 24px,但卡片底部看起来仍「刚好贴住」,很容易误判成没问题。
|
||||
- **原因**:文字区原本是 `grid min-h-0 content-start gap-2 overflow-hidden`,行高由 auto 轨道决定。auto 轨道的 max-content 高度对可换行文本等于**一行**的高度:标题拿到 14px(实际需要 20)、简介 14px(两行需要 32)、标签 14px(需要 19),只有最后一个子项(按钮行)拿到完整高度。真实浏览器实测 `clientHeight`/`scrollHeight` 为 14/20、14/32、14/19。jsdom 不计算布局,单测全绿也照不出来。
|
||||
- **处理(现行口径)**:文字区改 `flex flex-col`,每行写死高度并加 `shrink-0`(标题 `h-5`、元信息 `h-4`、简介 `h-8`、标签 `h-5.5`、按钮行 `h-7`,内边距 `p-3`、行距 `gap-2`),行高契约按同一组分项常量(`TEMPLATE_CARD_*_HEIGHT`)算出文字区 174。卡片行高、`TemplateCard` 类名与这组常量必须同时改。
|
||||
- **写死高度的连带约束**:动作行一旦固定成 `h-7`,那它就**只能放两个按钮**。再往里塞第三段文本(当时的「正在下载模板」)时,最小卡宽 250px 下按钮文案会被挤成两行并顶出卡片(用户看到「使用模 板 / 更 新」叠成一团)。现行口径是忙状态写在触发它的按钮上(`下载中` / `创建中`,按钮就地换图标+文案),按钮一律 `whitespace-nowrap shrink-0`,动作行 `overflow-hidden` 兜底。
|
||||
- **验证**:真实浏览器逐行核对 `clientHeight === scrollHeight`(20/20、16/16、32/32、22/22、28/28);单测钉住分项常量与卡片各行类名(`templateLibraryGrid.test.ts`、`templateLibraryView.test.tsx`)。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/features/template-library/templateLibraryGrid.ts`、`apps/ai-game-creator-shell/src/view/template-library/TemplateCard.tsx`、`docs/technical/【技术方案】AGC模板库与模板建项-2026-09-17.md`(卡片列表虚拟滚动)。
|
||||
|
||||
## 2026-09-22 筛选 chip 的选中态只靠低透明度色相微调,用户看不出选中了什么
|
||||
|
||||
- **现象**:模板库筛选 chip 选中与未选中的底色实测只差 **1.09:1**(选中 `rgba(238,208,183,0.26)` 合成后 ≈ `#f9eee5`,未选 ≈ `#fdf9f5`),选中文字 `#b76038` 在自己底色上只有 3.88:1(低于 AA);运行时分段选中的白底 pill 也和米色页面几乎同色。反馈原话是「选中和没选中的颜色都看不出有差别」。
|
||||
- **原因**:选中态走的是 `--platform-cool-bg/border/text`,这三个变量在浅色皮肤里是同一个暖色调的低透明度版本(bg 26%、border 24% alpha),只够做「淡淡的染色」,不足以表达二元状态;深色皮肤里 `rgba(8,145,178,0.14)` 同样太弱,而深色皮肤里「更深的填充」反而更不可分辨。
|
||||
- **处理(现行口径)**:筛选控件的二元状态统一为**未选 = 浅底描边 + 常规文字,选中 = 实心品牌填充 + 反白文字**(`.platform-category-chip--active` 与 `PlatformSegmentedTabs` 的 `tone="accent"` 共用 `--platform-chip-*` 语义色;深色皮肤用「亮填充 + 深文字」,因为深色下只有更亮才算选中)。改色只改 `packages/shared/src/theme.css` 的语义变量,不要再往组件里写颜色。
|
||||
- **同一坑的第二种表现**:把「悬停」也刷成品牌色(暖色描边 + 暖色文字)后,未选中的 chip 一悬停就像已选中——品牌色一旦被悬停借走,「已选中」这个强状态就没有颜色可用了。现行阶梯是「静止 = 浅底中性描边 / 悬停 = 中性加描边 + 极淡暖底 + 深色文字 / 按下 = 再压一层 / 选中 = 实心填充 + 反白文字」。客户端实测:选中填充 `#b0522e` vs 悬停底 `#f9efe4` = 4.52:1,选中 vs 静止 = 4.97:1,悬停 vs 静止 = 1.10:1(只是提示,不抢选中)。
|
||||
- **验证**:`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts` 按 WCAG 公式断言两套皮肤都满足「选中标签文字 ≥ 4.5:1(渐变两端都要过)」且「选中填充 vs 未选底色 ≥ 3:1」;真实浏览器实测改后两态对比 5.6–6.1:1、选中文字 5.5–6.0:1(改前分别是 1.09:1 与 3.88:1)。
|
||||
- **关联**:`packages/shared/src/theme.css`、`packages/shared/src/components/styles.css`、`packages/shared/src/components/PlatformSegmentedTabs.tsx`、`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts`。
|
||||
|
||||
## 2026-09-22 虚拟网格按「包裹层宽度」算列宽,经典滚动条一出现就多出横向滚动条
|
||||
|
||||
- **现象**:AGC 模板库卡片区底部在客户端里凭空多出一条横向滚动条(外层并没有横向溢出内容);窗口放到没有竖向滚动的尺寸时又不出现。
|
||||
- **原因**:react-window 的内层宽度 = `列数 × 列宽`,而列宽是按**包裹层**宽度算的(`floor(容器宽 / 列数)`)。经典(非 overlay)滚动条会吃掉 grid 外层的 `clientWidth`:Windows / WebView2 上竖向滚动条约 17px,于是内层 1184 比外层可用宽 1167 宽出正好一个滚动条,react-window 就按「横向也要滚」处理。**Playwright 自带的 Chromium 用的是 overlay 滚动条(占宽 0),本地量 `offsetWidth - clientWidth` 是 0,完全复现不出来** —— 这类问题只能在 WebView2 客户端里看,或者按算术推。
|
||||
- **处理(现行口径)**:`computeTemplateGridLayoutWithScrollbar`(`templateLibraryGrid.ts`)在「内容确实会竖向溢出」时先把滚动条宽度从容器宽度里扣掉再算列宽/行高,不竖向溢出时不预留(否则右侧会留一条无意义的白边);滚动条宽度由 `measureVerticalScrollbarWidth()` 量一次(overlay 平台为 0,逻辑自动退化)。同类虚拟列表再出现「莫名其妙的横向滚动条」,先查这里的算术,不要靠 `overflow-x: hidden` 掩盖(那会把最后一列切掉)。
|
||||
- **验证**:`templateLibraryGrid.test.ts` 断言「竖向溢出时 `列数 × 列宽 ≤ 容器宽 - 滚动条`」「不溢出或 overlay 时与不预留完全一致」;真机客户端截图确认横向滚动条消失、右侧只剩竖向滚动条。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/features/template-library/templateLibraryGrid.ts`、`apps/ai-game-creator-shell/src/view/template-library/index.tsx`。
|
||||
|
||||
## 2026-09-22 「15% 透明度的焦点环」等于没有焦点提示;选中态自己的投影还会把焦点环顶掉
|
||||
|
||||
- **现象**:键盘 Tab 走到筛选 chip、开关、卡片按钮上时,屏幕上完全看不出焦点在哪;自动化里更隐蔽——`box-shadow` 计算值非空(一串 `rgba(0,0,0,0) 0 0 0 0` 的 Tailwind ring 占位),只查「有没有 shadow」会全部判过。
|
||||
- **原因**:两个叠加的问题。① `--platform-input-focus-ring` 是 `rgba(204,117,76,0.15)`,合成到页面底色后对底色只有 **1.17:1**,远低于 WCAG 非文本对比要求的 3:1;② 焦点环用 `box-shadow` 画,而**选中态自己也有 `box-shadow`**(实心 chip 的投影),选中的 chip / 分段项聚焦时环被状态投影盖掉,等于没有提示。
|
||||
- **处理(现行口径)**:`--platform-input-focus-ring` 改成实心色(浅色 `#b6623f`,对页面 4.3:1;深色 `#9fb0ff`,对深色底 6.5:1);筛选 chip / 分段项 / 排序按钮的焦点环改用 `outline: 2px solid var(--platform-input-focus-ring); outline-offset: 2px`——`outline` 不参与 `box-shadow` 层叠,不会被选中态投影顶掉,也不撑开布局。
|
||||
- **验证**:`tests/workbenchThemeContrast.test.ts` 断言焦点环对两套皮肤的页面底色 ≥ 3:1;真实浏览器里对页面上**全部 175 个可聚焦控件**做 blur→focus 前后比对,无一例外都能看到焦点变化(改前有 8 个控件聚焦前后完全一致)。查焦点态时必须比较「聚焦前后的计算样式差异」,不能只看属性是否非空。
|
||||
- **关联**:`packages/shared/src/theme.css`、`packages/shared/src/components/styles.css`、`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts`。
|
||||
|
||||
## 2026-09-22 封面图加载失败会画出浏览器的「裂图」图标
|
||||
|
||||
- **现象**:模板清单里的封面 URL 失效(或离线)时,卡片封面上出现浏览器的破碎图片图标,比没有封面更难看。
|
||||
- **处理**:`TemplateCard` 的 `img` 加 `onError` 直接把自身 `visibility` 设为 `hidden`(不进 state,卡片是 memo 的纯展示组件),留下封面容器本身的中性底色;单测用 `fireEvent.error(cover)` 钉住。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/view/template-library/TemplateCard.tsx`、`apps/ai-game-creator-shell/tests/templateLibraryView.test.tsx`。
|
||||
|
||||
## 2026-09-23 渠道 `--config` 只写窗口标题,打包产物系统标题栏回来了且登录请求被 ACL 拒绝
|
||||
|
||||
- **现象**:dev 渠道 0.1.129 安装包启动后,窗口顶部同时出现系统标题栏(浅蓝条 + 原生最小化/最大化/关闭)与前端自绘 `WindowChrome`;窗口缩到 816x639(约 800x600 客户区);登录页常驻「无法连接登录服务,请确认配套后端或 API 代理已启动后重试」。应用日志同一秒出现 `startup.window-title.failed: 缺少 client 主窗口`,而 `https://dev.genarrative.world` 在浏览器/curl 下可正常响应。
|
||||
- **原因**:`ebb288a6a`(2026-09-23 18:49)为统一渠道产品名,在渠道配置里加了 `app: { windows: [{ title: productName }] }`。Tauri 的 `--config` 合并是 JSON Merge Patch(`tauri-utils/build.rs` 用 `json_patch::merge`):对象递归合并、**数组整体替换**。基线窗口数组被整条换掉后,`label` 回落到默认 `main`(不是 `client`)、`decorations` 回落到 `true`、尺寸回落到 800x600。三条症状同源:① `decorations: true` → 系统标题栏;② 尺寸回落 → 816x639;③ label 不再是 `client` → `capabilities/main.json`(`windows: ["client"]`,承载 `http:default` 与平台 API scope、dialog/opener/updater/剪贴板权限)整条不命中,前端 `fetchClientHttp` 走 `@tauri-apps/plugin-http` 时被 ACL 拒绝并抛错,登录状态检查就报成"连不上服务器"。判断关键:**这类"连不上服务"是权限拒绝,不是网络故障——先看窗口 label 与 capability 的 `windows` 是否还对得上,别去查后端与代理**。
|
||||
- **处理(现行口径)**:`createChannelConfig()` 从基线 `src-tauri/tauri.conf.json` 读完整 client 窗口对象后展开、只覆盖 `title`(`readBaseClientWindow()`),渠道配置不得再出现"只写 `title`"的窗口对象。新增守卫:`build-release.test.mjs` 用同语义的 merge patch 复现 Tauri 合并并断言 `label=client` / `decorations=false` / 1280x800 / min 1280x720 且承载 `http:default` 的 capability 必须包含该 label;`check-config.mjs` 增补基线 `decorations !== false` 失败关闭。
|
||||
- **验证**:`node --test apps/ai-game-creator-shell/scripts/build-release.test.mjs scripts/cargo-features.test.mjs scripts/release-oss.test.mjs scripts/prepare-macos-codex.test.mjs`(60/60)、`node apps/ai-game-creator-shell/scripts/check-config.mjs` 通过;`createChannelConfig('dev', …)` 实测输出含 `label: client` 与 `decorations: false`。修复后的安装包尚未重新构建与安装,真机观感与登录链未复核。
|
||||
- **关联**:`apps/ai-game-creator-shell/scripts/build-release.mjs`、`apps/ai-game-creator-shell/scripts/build-release.test.mjs`、`apps/ai-game-creator-shell/scripts/check-config.mjs`、`apps/ai-game-creator-shell/src-tauri/capabilities/main.json`、`docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md`。
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
## 开发中
|
||||
|
||||
- DirectProject 工具可并行调度,依赖由调用方等待,同资源事务与付费动作幂等不能放松。Web 创作先用客户端环境预检,分层验证共用持久的 `validation.maxRuns`,不改写 Provider 的 `llm.maxRetries`;成功证据按输入指纹复用,达标后交付。模型请求计时只保存安全元数据与可观测边界,未知不补零,写盘不能阻塞响应流。详见 AGC 主专题的“DirectProject 交付效率与可观测性”。
|
||||
- DirectProject 工具可并行调度,依赖由调用方等待,同资源事务与付费动作幂等不能放松。Web 创作先用客户端环境预检,分层验证共用持久的 `validation.maxRuns`,不改写 Provider 的 `llm.maxRetries`;成功证据按输入指纹复用,达标后交付。完整回合条目统一保存在 `project.jsonl`;旧平行审计和附属请求分段计时已退出生产入口,不能因残留实现或测试而恢复旧契约。界面生命周期耗时与独立模型使用记录继续有效,未知边界不补零。详见 AGC 主专题的“Direct 历史、审计与耗时的现行边界”。
|
||||
|
||||
- DirectProject 源码修改走 `agc_apply_patch`、进度走 `agc_update_plan`:SDK 原生的 `apply_patch` / `update_plan` 注册会被按回合移除(全局串行单例),不要恢复它们或用伪造工具注解换取并发。补丁只在当前项目内、受当前回合 Write 许可和受控进程约束,失败可能已部分写入,未知结果不自动重放;计划完成不构成验收证据。
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
- 画布卡片类型与信息角标共用 `CanvasCardCornerActions`;菜单收纳共用 `OverflowActions`,宿主决定展示数量和资源命令。AGC 选中菜单前 5 项直显,Web 默认不折叠;浮层 portal 继续接入现有画布关闭与滚轮归属判据。
|
||||
- 修改范围保持聚焦;优先扩展现有系统、页面、组件、DTO 和脚本。
|
||||
- Agent 可见内容直接描述当前任务、输入和成功条件,细节按调用需要提供。
|
||||
- AGC 外置智能体提示词只写模型必须遵守的指令与契约(工具名与参数、调用顺序、禁止项、失败处理、产物要求),不写客户端/宿主怎么实现:内部预算字段与限额、内部状态机与枚举、执行器锁与沙箱技术栈、进程/插件部署、注入与投影管线都属于宿主实现,一律改写成对应行为要求或删除。
|
||||
- 修改提示词文本时保留原有 `{...}`/`{{...}}` 占位符;确需增删占位符必须同步改对应 Rust 调用点与断言该文本的测试。
|
||||
- UI 开发优先复用现有公共组件;跨页面或跨端重复的视觉/交互模式应沉淀到 `packages/shared`,由现有页面迁移使用。共享组件承载通用表现与交互,领域规则、后端副作用和正式业务状态由后端负责。
|
||||
- AGC 当前 Agent 与策划 Agent 的消息层级共用 `packages/shared` 的 `AgentMessageContent`:正文使用 `body`,思考、中间输出与工具调用使用 `process`;过程字号和颜色由共享组件统一定义,错误状态保留语义色。
|
||||
- 后端遵循 `module-*`、`spacetime-module`、`spacetime-client`、`api-server`、`platform-*`、`shared-contracts` 的现役边界。
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
## 指标口径
|
||||
|
||||
- 生产素材数:`editor_project_resource` 中 `source_type = 'generated'` 的资源,按 `created_at` 映射到北京时间业务日。
|
||||
- 消耗泥点数:`profile_wallet_ledger` 中 `source_type = asset_operation_consume` 且 `amount_delta < 0` 的流水绝对值,按 `created_at` 映射到北京时间业务日。
|
||||
- 消耗泥点数(净消耗):`profile_wallet_ledger` 中 `source_type` 为 `asset_operation_consume` / `llm_router_consume` 且 `amount_delta < 0` 的流水绝对值,按 `created_at` 映射到北京时间业务日后,再按日对冲同期退还泥点——先抵当日消耗,不足再回溯抵扣最近仍有净额的业务日,抵扣不完的退还丢弃,因此每日净额非负,区间合计严格等于「消耗 − 退还」。充值退款追回、余额重置、赠送和 hold 都不计入。
|
||||
- 退还泥点数:`source_type = asset_operation_refund` 的正向流水(生成失败退还、精选审核返还)与 `llm_router_consume` 的正向冲正流水,按 `created_at` 映射到北京时间业务日。它只对冲本看板的消耗口径,不改变用户详情「历史花费」按既有决策的退款不冲减口径。
|
||||
- 总注册用户:`profile_dashboard_state` 行数。
|
||||
- 新增用户数:`profile_dashboard_state` 中 `created_at` 落在当前筛选时间窗内的账号数,按北京时间业务日归属,支持本日 / 本周 / 本月快捷日期范围。
|
||||
- 新增用户付费率:分母为当前筛选时间窗内的新增用户,分子为这些用户中截至本次查询时已至少完成一次真实支付的去重人数。真实支付以 `profile_recharge_order.paid_at` 存在且不晚于本次查询时刻为准;只创建订单或未支付订单不计,已退款订单仍表示曾经发生过付费转化,因此保留在分子。返回付费人数、新增用户数和四舍五入后的基点率;分母为 0 时 DTO 返回 0,前端百分比显示 `-`。
|
||||
@@ -33,6 +34,7 @@
|
||||
- 留存活跃:用户在注册日恰好 `D+1` / `D+7` 的 `tracking_daily_stat` 中存在上述有效 user scope 行;同一用户同日多个事件只计一次,不按“1 / 7 天内累计回访”计算。筛选范围约束注册 cohort,观察日允许晚于筛选结束日。
|
||||
- 留存成熟条件:目标观察日必须早于当前北京时间业务日;观察日为今天时因当天尚未完整结束而排除。D1、D7 的可观察人数通常不同,分别返回 `eligibleUsers`、`retainedUsers` 与 `rateBasisPoints = round(retainedUsers * 10000 / eligibleUsers)`;分母为 0 时 DTO 返回 0,前端百分比显示 `-`。汇总率按总人数加权,不平均每日百分比。
|
||||
- 运营汇总页签:复用同一时间窗,展示运营指标卡、素材类型分布和访问模块分布。
|
||||
- 趋势图:`消耗泥点` 图展示按日对冲之后的净额,区间合计与「消耗泥点数」指标一致;`退还泥点` 图展示同期退还金额,毛消耗可由「消耗 + 退还」核出,避免把退还金额藏进净额里。
|
||||
|
||||
## 前后端文件
|
||||
|
||||
|
||||
@@ -488,7 +488,7 @@ dev 根盘空间在安装后曾接近满盘;2026-06-17 进入 canary 前已清
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_ACME_ROOT` | `/var/www/html` | ACME challenge 静态目录。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_MAINTENANCE_FILE` | `/var/lib/genarrative/maintenance/enabled` | 存在即进入维护模式。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_FORWARDED_PROTO` | `http` | 写入 `X-Forwarded-Proto` 的值。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_MAX_API_BODY_BYTES` | `67108864` | `/api` 通用路由的 `Content-Length` 上限。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_MAX_API_BODY_BYTES` | `220200960` | `/api` 通用路由的 `Content-Length` 上限(210 MiB,覆盖游戏发行包 PUT 的 200 MiB + 1 KiB 路由上限)。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_COMPRESSION_ALGORITHMS` | `gzip` | 当前唯一允许的压缩算法白名单;Pingora 正式化口径固定为 gzip-only,Brotli 继续由 Nginx / 前置代理承担。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_GZIP_ENABLED` | `true` | 是否启用 gzip 响应压缩。 |
|
||||
| `GENARRATIVE_PINGORA_GATEWAY_GZIP_LEVEL` | `5` | gzip 压缩等级,必须在 `0..=9`。 |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user