合并最新主分支并同步资源管理修复
合入智能体协作提示词与游戏验收边界更新 保留资源管理审核修复与合并后门禁整理 # Conflicts: # docs/project-memory/shared-memory/pitfalls.md
This commit is contained in:
@@ -4048,6 +4048,14 @@
|
||||
- 验证:`external_editor_api.rs` 的 openapi 断言只校验 schema 形状,不校验兼容性,通过不等于契约安全;判定 breaking 与否以「删字段、移出 required、收窄类型、改语义、新增必填」为准。
|
||||
- 关联:`docs/【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md`、`docs/openapi/genarrative-external-v1.openapi.json`、`server-rs/crates/api-server/src/external_editor_api.rs`、`server-rs/crates/api-server/src/modules/external_api.rs`。
|
||||
|
||||
## “继续”不能成为新游戏主题或触发首版整文件覆盖(2026-08-03)
|
||||
|
||||
- 现象:原根 run 已经写出并验证目标玩法,但父 Runtime 因预算、上下文或 Provider 失败;用户在同一项目输入“继续”后,页面标题变成“继续”,玩法被默认收集/点击模板替换,美术规范总览图被直接铺进游戏画面。
|
||||
- 原因:终态失败 run 不能 steer,提交层因此创建 task 只有继续短语的新 root;每个新 autonomous 根合同又无条件 reset seed manifest;game-chat fallback 从当前 root task 取主题并直接 `file.write game/index.html`。同时快车道把 `icon-spec` 误当运行素材,要求整图背景和象限裁剪实体。通用 smoke/generic playtest 只验证结构与最小交互,无法发现玩法目标已经漂移。
|
||||
- 处理:严格继续意图必须在同一 Supervisor Session、同一持久 source 内继承最近失败根 run 的原始目标和 baseline,但保持新的 run/Provider/sidecar 身份;纯继续词表只能有一个权威实现,中英文短语都走同一入口,真正新需求仍独立 reset。非占位入口禁止 fallback 整体覆盖,也不能反复运行只读 smoke;当前 `code-prototype` 必须先读取并实际 patch,取得本人 mutation 后才能验证和交付。占位 fallback 只支持具备真实语义的显式模板,俄罗斯方块必须实际实现棋盘、下落、旋转、锁定和消行,未知玩法失败关闭。`art-spec.png` 只作规范参考,核心运行时位图必须来自独立派生的透明 `art-spritesheet.png` 及其 `iconImageSrcs` 本地切片;切片清单绑定当前图集 resourceId,Canvas 分别使用玩家、目标、场景和反馈四类素材。不得猜测图集是 2×2 等分、把规范板塞进画面或以纯代码核心实体绕过派生素材。
|
||||
- 验证:覆盖失败根任务“水晶俄罗斯方块”后输入“继续”、连续 successor、跨 Session、跨 source、正常完成后新输入、带具体新需求、既有非占位入口先 patch 后 smoke、初始化占位的俄罗斯方块真实语义、未知玩法失败关闭、纯继续目标缺失、规范图不在运行 DOM/Canvas、真实动作前后 `sequence` 与 RAF 空转。浏览器验收必须同时比较 baseline 玩法关键文本/控件/状态和当前 revision,不能只看 Canvas 非空与三个固定按钮。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/game_chat_fast_path.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_request_builders.rs`。
|
||||
|
||||
## Tauri beforeDevCommand 失败不等于已启动客户端会自动退出(2026-08-03)
|
||||
|
||||
- 现象:旧 worktree 的 AGC Vite 长期占用 `127.0.0.1:3080`,marker 仍指向旧 API;新 worktree 启动 game-chat 后,配套后端在新端口 ready,随后 `beforeDevCommand` 因代理 target 不匹配返回非零,终端已经回到提示符,但原生客户端和它启动的 Runner 仍存活。客户端 WebView 实际加载旧 Vite,因此当前 master 的界面优化看起来全部缺失。
|
||||
@@ -4068,7 +4076,7 @@
|
||||
|
||||
- 现象:生成提交发生客户端超时、连接中断或响应丢失后,调用方创建新的 `Idempotency-Key` 再提交一次;原任务其实已经入队,最终造成重复生成、重复扣费和重复画布 / 素材库写入。
|
||||
- 原因:把“客户端没有收到结果”误判为“服务端没有受理”,又没有持久保留逻辑请求的幂等键和服务端返回的 `operationId`。托管 MCP 若绕过 External REST router 直接调用 worker 或 SpacetimeDB,也会形成第二套去重与状态语义。
|
||||
- 处理:一次逻辑生成只分配一个稳定幂等键。桌面 Runtime 在 POST 前先把精确请求体、SHA-256 和幂等键原子写入私有生成账本并回读一致;收到 `202 + operationId` 后先把账本升级为 `accepted` 再轮询。重启时 `accepted` 只恢复 GET,`prepared`、响应丢失、`202` 缺 operationId、轮询超时和状态损坏都进入 `needs-reconciliation`,绝不自动 POST。game-chat 五分钟硬截止可以结束本轮、关闭预览和客户端,但 executing 的 `canvas.asset_generate` 必须保留 pending action、provider batch 与生成账本;旧 `200` 图集的 `spritesheetResource` 允许为空,此时只在顶层 `spritesheetImageSrc` 是有效下载引用时优先使用,否则回退可用 `objectKey`。`postprocess-failed-source-preserved` 进入不可自动重生的对账边界;其它 non-blocking warning 继续消费成功结果并单独展示。旧 `200` 兼容不改变权威 External v1 的异步契约。MCP 生成工具必须把 `idempotencyKey` 映射到同一 REST header,并复用同一 External router、owner 和任务账本。
|
||||
- 处理:一次逻辑生成只分配一个稳定幂等键。桌面 Runtime 在 POST 前先把精确请求体、SHA-256 和幂等键原子写入私有生成账本并回读一致;收到 `202 + operationId` 后先把账本升级为 `accepted` 再轮询。重启时 `accepted` 只恢复 GET,`prepared`、响应丢失、`202` 缺 operationId、轮询超时和状态损坏都进入 `needs-reconciliation`,绝不自动 POST。game-chat 的 4500 秒硬截止可以结束本轮、关闭预览和客户端,但 executing 的 `canvas.asset_generate` 必须保留 pending action、provider batch 与生成账本;旧 `200` 图集的 `spritesheetResource` 允许为空,此时只在顶层 `spritesheetImageSrc` 是有效下载引用时优先使用,否则回退可用 `objectKey`。`postprocess-failed-source-preserved` 进入不可自动重生的对账边界;其它 non-blocking warning 继续消费成功结果并单独展示。旧 `200` 兼容不改变权威 External v1 的异步契约。MCP 生成工具必须把 `idempotencyKey` 映射到同一 REST header,并复用同一 External router、owner 和任务账本。
|
||||
- 补充:不能把“accepted 分支里没有生成 POST”误当成 GET-only 恢复。若读取账本前仍重做项目/素材目录准备、输出路径预检或请求正文构造,恢复仍可能创建远端资源或在查询 operation 前失败。恢复必须直接使用 durable snapshot;清理必须最后删除 pending 身份锚点,活动 orphan 不得自动删除。完整恢复 future 还要在默认 Tokio worker 栈下验证,不能靠测试环境调大 `RUST_MIN_STACK` 掩盖栈溢出。
|
||||
- 加固:durable snapshot 必须绑定不含明文凭据的 base URL/API Key 配置指纹,配置漂移时连 GET 也必须阻断。accepted operation 明确 failed 也不能在 observation 持久化前删账本。旧 `200` durable result 只保留允许字段与安全 objectKey/相对路径,签名 URL、query/fragment 和未知字段不落盘。提交只有契约明确的 `400 / 401 / 403` 可证明未入队并清理 prepared 账本;超时、冲突、限流、网关错误及其它意外状态均保留账本进入对账。账本根目录、扫描和删除必须通过受控路径解析逐级拒绝符号链接,不能让项目内链接把清理目标指向项目外。
|
||||
- 验证:覆盖“服务端已入队但提交响应丢失”后原键重试仍返回同一 operation、换 owner 不可见、查询最终只出现一份 completed result 和一次计费 / 写回;MCP 与 REST 对同一 owner、同一请求和同一键必须命中同一 operation。
|
||||
@@ -4106,3 +4114,17 @@
|
||||
- 原因:测试触发了与断言无关的账户读取,较快环境中请求会在用例结束前失败,较慢 CI 中请求延迟到组件和 jsdom 均已销毁后才收束。仅用 revision 丢弃旧请求而不在卸载时推进 revision,最后一个在途请求仍会被误认作当前请求。
|
||||
- 处理:调用方在未认证时不得启动受保护的钱包刷新;可取消的读取要为每轮分配 `AbortController`,新读取先失效并中止旧读取,组件卸载时同时推进 revision、abort 当前请求并清空句柄。所有 `then / catch / finally` 在更新状态前都要检查 signal 与 revision。
|
||||
- 验证:定向测试覆盖卸载后请求 signal 已中止;同时复跑触发钱包刷新回调的画布生成集成测试和完整前端测试,不能以单文件偶然快速收束代替全量验证。
|
||||
|
||||
## 不要用自然语言精确 `.replace()` 维护 Runtime Prompt
|
||||
|
||||
- 现象:Prompt 文案稍作改写、增删空格或调整段落后,替换静默失效,代码中出现难以审阅的链式 `.replace()`。
|
||||
- 原因:把自然语言全文同时当内容和结构锚点,没有稳定 section 身份。
|
||||
- 处理:稳定片段拆为版本化 Bundle section,由 Rust 显式按角色、平台和配置组合;`agent_runtime_native_executable_tools()` 是原生可执行工具的权威源列表,同时供 Prompt 工具目录与 native capability registry 使用,`mcp.call` 只服从当前请求的动态 MCP catalog。最终 Provider 请求构建器同样必须使用显式 section 与条件组合,不能以后置自然语言精确 `.replace()` 注入工具合同、平台规则或角色规则。安全规则保留在代码中。
|
||||
- 验证:manifest 覆盖所有嵌入资源、版本一致、源列表中的原生工具全部进入 Prompt 与 native capability registry、`mcp.call` 不进入静态目录、Supervisor section 顺序和关键角色合同保持不变,并扫描 `prompt.rs` 与最终 Provider 请求构建器不再出现自然语言链式 `.replace()`;对最终 Provider 请求直接断言各角色、平台和配置分支的合同内容。
|
||||
|
||||
## 动态 MCP 函数参数不能只依赖 Provider schema
|
||||
|
||||
- 现象:动态 MCP 函数虽然带 catalog `inputSchema`,Runtime 却只检查 `arguments.input` 是 object;非 strict 或兼容 Provider 可以返回缺 required、类型错误、enum 外值或 schema 外隐藏字段,并把它们原样送到外部工具。
|
||||
- 风险:Provider 工具约束不是本地安全边界;特别是 `writes + readOnlyHint=true` 自动放行的工具,schema 外字段可能改变外部副作用而不进入预期确认路径。
|
||||
- 处理:使用完整 JSON Schema validator 校验原始 catalog schema,不手写 required/type 子集;native parser、fingerprint enrichment 与实际 MCP 调用边界复用同一校验器。enrichment 错误必须映射回 classified `arguments-schema` repair,不能以普通字符串直接终止 run;执行点重验用于阻断升级前已经落盘的 schema 外 pending。关闭网络和文件 `$ref` 解析,schema 无法安全编译时不广告或不执行。`serde` 类型错误会包含实际字符串值,catalog miss 也会包含模型提交的 server/tool,因此这两类错误同样只能返回稳定类别,不能拼接原始错误、参数值或 schema 内容。
|
||||
- 验证:覆盖 required、additionalProperties、type、enum、本地 `$defs/$ref`、HTTP/file 外部引用、无效 schema、错误脱敏,证明 legacy wrapper 在注入 fingerprint 前进入 repair,并证明带旧有效 fingerprint 的历史 pending 在实际调用前仍被 schema 拒绝。
|
||||
|
||||
Reference in New Issue
Block a user