From 912df59c2b07d1f82d85fe3166fa45649af94456 Mon Sep 17 00:00:00 2001 From: menghao Date: Tue, 11 Aug 2026 17:43:49 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E9=99=90=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E4=B8=B4=E6=97=B6=E4=BF=AE=E5=A4=8D=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除已完成阶段使用的临时修复清单。 保留权威技术文档与项目共享记忆中的稳定结论。 继续排除本地环境文件与手工验证产物。 --- ...计划】Tauri无限画布审查缺陷闭环-2026-08-11.md | 297 ------------------ 1 file changed, 297 deletions(-) delete mode 100644 docs/project-memory/plans/【修复计划】Tauri无限画布审查缺陷闭环-2026-08-11.md diff --git a/docs/project-memory/plans/【修复计划】Tauri无限画布审查缺陷闭环-2026-08-11.md b/docs/project-memory/plans/【修复计划】Tauri无限画布审查缺陷闭环-2026-08-11.md deleted file mode 100644 index a6c85e909..000000000 --- a/docs/project-memory/plans/【修复计划】Tauri无限画布审查缺陷闭环-2026-08-11.md +++ /dev/null @@ -1,297 +0,0 @@ -# Tauri 无限画布审查缺陷闭环计划 - -日期:`2026-08-11` - -状态:`最终差异审查重新打开 S2、S4、S5;正在并行修复 1 个 P1、8 个 P2 和 1 个合同一致性 P3,计划必须继续保留` - -适用分支:`codex/infinite-canvas` - -当前本地基线:本轮工程修复提交为 `ca59fa496`,随后通过 `c8c0c6deeb42278635736c7825781bfd32b963a4` 融合 `origin/master 3c457feb4`;当前分支相对 `origin/master` 为 `ahead 67 / behind 0`,远端 `origin/codex/infinite-canvas` 仍为 `9ff16393e0`。用户本地 `.env`、`.env.local`、`output/manual-validation/` 继续排除;本段只记录本地融合基线,不能代替精确最终 head 的远端 CI 与审查证据。 - -关联权威文档: - -- [`AI 游戏创作智能体 App 实施计划`](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md) -- [`AI 游戏创作项目开发工作台 PRD`](../../prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md) -- [`项目决策日志`](../shared-memory/decision-log.md) -- [`项目踩坑记录`](../shared-memory/pitfalls.md) - -> 本文是本轮缺陷修复的临时唯一执行清单。后续 Agent 开始相关工作前必须先读本文,逐项更新“实施状态”和验证证据,不得因为上下文切换跳过未完成项。只要还有未完成、未验证、未融合、未通过远端 CI 或需人工确认的事项,本文就必须继续保留在仓库中。 - -## 一、目标 - -1. 修复资源编辑恢复账本、manifest / project revision 崩溃窗口和恢复队列阻塞问题。 -2. 修复无限画布草稿乱序回包、失败态误导、Shift 选择分叉和零位移撤销污染问题。 -3. 为升级前包含 Developer API Key 的图片生成账本提供显式、安全、可验证的服务身份迁移路径。 -4. 融合最新 `master`,补齐回归测试、权威文档、提交规范和远端 required CI 证据。 -5. 保持现有非破坏性编辑语义:任何编辑都创建新资源,原资源、原文件和原版本不得被覆盖或删除。 - -## 二、绝对边界 - -- 不修改、暂存或提交 `.env`、`.env.local`、`output/manual-validation/` 及任何用户本地配置、凭据、日志或构建产物。 -- 不通过重发新生成请求来“恢复”已经受理、可能已扣费或结果未知的 operation;恢复只能使用私有账本冻结的 endpoint、原始请求字节、幂等键和 operationId。 -- 不把 API Key、Authorization、上传 ticket、签名 URL、Provider 正文或绝对路径写入账本、前端 DTO、日志、测试 fixture 或文档。 -- 不在 Tauri 宿主复制共享画布 core 已有的选择、变换、renderer 或 history 规则;优先复用 `packages/image-canvas-core` 和 `packages/image-canvas-react`。 -- 不修改 `/api/external/v1` 路由、HTTP 方法或公开 DTO;如果实施中确实需要改公开契约,必须暂停,补齐 OpenAPI 与契约测试后再继续。 -- 不修改 SpacetimeDB schema。本轮若发现必须修改 schema,立即暂停并先确认迁移计划。 -- 不为已退役入口增加兼容代码、测试、注释或文档。 -- 不执行真实付费生成;生成与恢复只用确定性单测或 loopback mock 验证。 - -## 三、当前问题与目标设计 - -### R0:远端分支与最新 master 尚未形成可信基线 - -现状:本地分支比本地 `origin/master` 少 2 个提交;其中 `4c0fdf180` 涉及画布改造恢复链路。截图中的远端 head 与当前本地 head 也不一致。 - -目标: - -- 先只读 fetch,核对 `origin/master`、远端 `codex/infinite-canvas`、PR head 和本地 HEAD 的祖先关系。 -- 先融合最新 master,再在融合后的源码上落修复;按合同解决 `Cargo.lock`、工作台 PRD 和 AI 游戏创作技术方案冲突,不能直接选择一侧覆盖。 -- 融合后重新定位下列函数与测试,禁止沿用截图旧行号。 - -### R1:远端明确 `failed` 后账本仍永久占用 pending 队列 - -现状:`wait_for_resource_edit_remote` 对 `status=failed` 只返回普通错误;`ResourceEditLedgerPhase` 没有远端终态失败或用户处置状态,`list_pending_local_project_resource_edits_at` 会继续列出该 operation。 - -目标设计: - -- 为私有账本增加可识别的远端终态失败,持久化稳定失败分类和终态时间,不持久化远端错误正文。 -- 区分三类状态:可安全继续、需要人工对账、远端明确失败。远端明确失败不得再次 POST、不得继续轮询、不得触发重复生成或扣费。 -- 增加“移出恢复队列”的显式处置。处置只把终态失败标记为已跳过/已归档,保留账本审计,不删除远端事实,不伪装 committed。 -- 不允许对结果未知、鉴权临时失败或 reconciliation-required operation 直接执行跳过;这些状态继续失败关闭。 - -验收:远端 `failed` 只轮询到一次终态,重启后仍为终态失败;恢复按钮不再被它永久占用;跳过后不再出现在活动恢复队列,但账本仍可审计,HTTP POST/GET、manifest、revision 和扣费相关调用均不增加。 - -### R2:资产 manifest、project revision 与账本提交之间存在崩溃窗口 - -现状:`commit_resource_edit_asset` 先写 manifest,再推进 project revision,最后才把 ledger 标记 committed。若进程在这些步骤之间退出,重启看到 manifest 已有 asset 时会直接把 ledger 标记 committed,却可能永远漏掉 revision。普通错误回滚不能覆盖进程崩溃。 - -目标设计: - -- 复用版本编辑现有 journal 思路,为资产提交增加 durable transaction journal;不要只在错误返回路径做内存回滚。 -- journal 至少绑定 operation/project/source、稳定 asset ID、最终相对路径、媒体摘要、base/target project revision、manifest before/after 身份和阶段。 -- 阶段覆盖:`prepared -> media-installed -> manifest-written -> revision-written -> committed`。每次推进都原子写入并回读;ledger 只能在 journal 证明 manifest、revision、文件与结果身份全部一致后进入 committed。 -- 恢复矩阵: - - manifest/revision 都是 before:安全继续或只清理能证明属于本事务的新文件; - - manifest 是 after、revision 是 base:只前向补目标 revision; - - manifest/revision 都是 after:补齐 journal、ledger 和结果投影; - - asset 重复、摘要冲突、revision 越过目标或 before/after 身份不一致:进入 reconciliation-required,禁止猜测回滚或再次生成。 -- 审计 `resource_editor.rs` 内其它“写 manifest 后推进 revision”的同类路径;能复用同一事务 helper 的一并收口,不能留下等价崩溃窗口。 - -验收:在每个阶段构造 crash fixture,重启恢复后始终只有一份派生文件和一条 manifest asset,revision 精确推进一次;“manifest 已写、revision 未写”的回归必须证明恢复补齐 revision,而不是直接 committed。 - -### R3:草稿 loadDraft 乱序完成会把新 revision 覆盖成旧 revision - -现状:`applyGenerationProgressRevision` 只把 load 回包与各自捕获的 progress revision 比较。r5 请求后发、r6 请求先回时,r5 仍可能覆盖已经落到 `draftRef.current` 的 r6。 - -目标设计: - -- load 回包落地前同时校验 scope epoch、回包 revision、触发该请求的最低 revision,以及“回包当下”的 `draftRef.current.revision`。 -- 只允许 revision 单调前进;相等回包只有完整身份与当前状态一致时才可幂等应用,任何较旧回包都丢弃。 -- 生成 progress、草稿保存队列和初始 hydration 使用同一单调规则,避免一处修复、另一处仍回退。 - -验收:用 deferred Promise 分别覆盖 r5/r6 正序和逆序完成、保存与 progress 交错、scope 切换和卸载;最终 draft 始终停在最高可信 revision,下一次保存不产生伪 revision conflict。 - -### R4:恢复 UI 只处理排序后的第一条 operation - -现状:工作台按钮固定读取 `pendingResourceEdits[0]`。一条不可恢复旧 operation 会永久挡住后续已受理或已下载、可能已扣费的 operation。 - -目标设计: - -- 顶部按钮只负责打开独立恢复面板,不在当前工具栏下方追加说明或列表。 -- 面板逐条显示安全名称、编辑类型、创建时间、当前阶段和允许动作;用户可以选择任意 operation 恢复。 -- 可继续项提供“继续”,reconciliation-required 提供只读对账提示,远端终态失败只提供“移出恢复队列”。 -- 单项执行期间只锁该 operation;其它行保持可见但避免重复提交。完成或处置后重新读取后端权威队列,不在前端猜测删除。 -- 列表读取失败必须显示可重试错误,不能静默伪装为空队列。 - -验收:至少构造三条乱序记录(首条终态失败、第二条可恢复、第三条需对账),证明第二条可以独立恢复、首条可以显式处置、第三条不会被误重放;项目切换后的迟到结果不能污染新项目面板。 - -### R5:升级前 Key-bound 指纹在旧 Key 已失效后没有恢复路径 - -现状:新代码只计算服务地址指纹,但旧账本可能保存 `H(baseUrl, H(oldKey))`。旧 Key 已轮换时,客户端既不能验证旧哈希,也不能确认当前地址就是原服务,结果只能永久 `configuration-changed`。 - -目标设计: - -- 为 generation ledger 的服务身份增加显式版本/方案标记,当前方案固定为规范 base URL 的 service fingerprint;新账本不再混入凭据。 -- 旧 Key 仍可用且旧指纹精确匹配时,可在任何远端动作前自动原子迁移为 service fingerprint。 -- 旧 Key 已失效、旧指纹无法验证时,不得自动接管。提供显式用户确认面板,显示脱敏的当前服务 origin 与旧 operation 状态;用户确认“当前地址就是创建该 operation 的原服务”后,Tauri 在项目锁/账本锁内重读配置与 ledger,再把身份原子迁移为 service fingerprint。 -- 确认命令只接收项目和 generation/operation 身份及防止陈旧确认的挑战值,不接收 Key、请求正文或任意 base URL;配置或账本在面板打开后变化时确认失败。 -- accepted/running 的旧账本迁移后只恢复原 GET;prepared/未知提交结果只有在确认后才允许用原 endpoint、原始正文和原幂等键重放原 POST。任何新 operationId、新正文或新键都禁止。 -- 该路径同时审计资源编辑与素材画布的服务身份实现,提取共享纯函数,避免再次形成两套指纹语义。 - -验收:必须补“旧 Key 已失效、升级后配置新 Key、用户确认当前服务、恢复旧 accepted operation”的回归;断言恢复只有 GET、operationId 不变、没有新 POST。另覆盖确认前零网络、确认挑战过期、服务地址改变、prepared 原请求精确重放和账本零凭据。 - -### R6:统一 `canvas.failed` 会误导用户执行生成重试 - -现状:草稿保存、revision 冲突、资源提交、取消/恢复和真实生成错误都进入同一失败 UI;可访问名称固定为“图片生成失败”,并统一提供返回修改/重新确认,可能让保存故障再次生成。 - -目标设计: - -- 失败状态携带稳定操作类别,例如 `generation / draft-save / asset-commit / recovery / cancellation`,错误码继续保持脱敏。 -- 使用纯映射函数按操作类别给出标题、`aria-label`、说明和允许动作。 -- 只有明确 generation 失败允许“返回修改/重新确认”;草稿保存或 CAS 故障提供保留草稿、重新加载或返回总览;资产 commit/result-unknown 只提供恢复/对账,不触发新生成;取消故障保留草稿处置入口。 -- 保留用户已填写的生成参数,不把失败分类修复误做成清空表单。 - -验收:逐类断言可访问名称和按钮集合;保存/revision/CAS/取消故障中不存在生成重试按钮,生成故障仍能返回原参数。 - -### R7:Tauri Shift 选择复制了共享 core,但语义已经分叉 - -现状:Tauri `onPointerDown` 自行实现 toggle;仅选中一个图层时 Shift 点击自身会删除最后一项。共享 `resolvePointerSelection` 已明确保留最后一项。 - -目标设计: - -- Tauri pointer 与键盘选择统一调用共享 `resolveLayerPointerSelection`/`resolvePointerSelection`,删除宿主内重复的数组增删算法。 -- 同一次 pointerdown -> pointerup -> click 序列只能切换一次;普通点击已选图层保持当前多选集合以支持拖拽,Shift 单选自身仍保留该项。 -- Web 与 Tauri 用同一组 core contract 测试锁定语义。 - -验收:覆盖单选自身 Shift、两项多选移除其中一项、向现有选择追加、已选多图层拖拽、键盘 Enter/Space 和 pointer 完整序列;两宿主结果一致。 - -### R8:pointerdown 立即写 history,零位移也触发撤销和保存 - -现状:图层 move/resize 和背景 pan 在 pointerdown 立即 capture,pointerup 无条件 mark dirty;单击已选图层或零位移序列会产生空撤销项并触发草稿 CAS。 - -目标设计: - -- pointerdown 只冻结初始快照和待定 history action,不立即压入 history。 -- 第一次产生有效 world delta、viewport delta 或 resize bounds 变化时只 capture 一次;pointerup 只有最终快照确实变化才 mark dirty。 -- 零位移、pointercancel 前无变化、锁定图层和仅保持原选择不得产生 history、documentVersion 或草稿保存。 -- 选择本身真实变化仍按草稿合同持久化,但与 move history 分开,不消费用户第一次撤销。 -- 优先复用共享 React stage hook 已有的 pending drag history 思路;若宿主事件形状不同,只保留最薄的 Tauri adapter 状态。 - -验收:单击已选图层后第一次撤销仍撤销上一个真实操作;零位移不调用 updateDraft;首次有效移动只产生一个 history entry 和一次 dirty;多次 pointermove 不重复 capture;取消/锁定/生成中均无副作用。 - -### R9:提交历史与远端审查闭环 - -现状:审查指出历史中存在英文 merge 标题和空正文;当前分支又是已发布的长分支,直接重写会影响协作者。 - -目标: - -- 本轮新提交全部使用中文标题,正文逐行说明一项修改;合并提交也遵守同一格式。 -- 修复完成后重新检查 Gitea 对“提交规范”的实际校验范围。若 required check 仍检查本分支全部历史,新增提交不能修复旧记录。 -- 未经用户明确批准,不 force-push、不改写共享分支历史。推荐方案是从最新 `origin/master` 新建替代分支,把最终差异整理为少量中文标题+逐行正文的提交并新建/替换 PR;若用户明确要求保留原 PR,再制定可回滚的历史重写方案并单独确认。 -- 精确 head 的四个 required CI 全绿且审查意见重新确认后,才算远端闭环。 - -## 四、实施顺序与状态 - -- [x] S0:fetch 并核对本地、远端分支、PR head、最新 master 和 dirty worktree;记录新的基线,保护用户本地文件。 -- [x] S1:融合最新 master,按权威合同解决冲突;运行冲突扫描、定向 typecheck/test 和 `git diff --check`。 -- [x] S2:实现 R1 + R2 后端账本状态与资产事务 journal,先写故障矩阵测试,再接恢复命令。最终审查发现的旧 committed version journal、committed 正式媒体异常、HTTP 400 终态分类,以及 202 非法 JSON / 缺 operationId 边界均已补齐并回归。 -- [x] S3:实现 R5 版本化服务身份与显式确认迁移,补旧 Key 已失效的恢复测试。 -- [x] S4:实现 R3、R7、R8 的共享交互与单调草稿规则,补 core/React/Tauri 回归。最终审查发现的 progress 读取失败重试和拖离后回到原点均已补齐并回归。 -- [x] S5:实现 R4、R6 的独立恢复面板与按操作分类失败 UI,完成键盘、焦点和移动端/桌面布局回归。最终两轮审查发现的后置权威重读隔离、失败重读、逐 operation 锁、modal focus trap、并发失败提示、动态禁用焦点和同项目重开 modal 竞态均已补齐并回归。 -- [x] S6:同步 AI 游戏创作技术方案、工作台 PRD、decision log 和 pitfalls;删除当前文档中已被新实现推翻的过度承诺。 -- [x] S7:完成改动范围内的定向验证与必要门禁,复核无敏感信息、无用户文件、无墓碑兼容和无公开契约漂移;定向结果未暴露需要升级完整 native-shell 门禁的跨模块风险。 -- [ ] S8:按 R9 处理提交历史与 PR,确认精确 head 的远端 required CI 和审查结论。已确认 `.gitea/workflows/project-ci.yml` 的四项 required job 不校验全部提交标题/正文,但 PR #136 review #210 明确把历史英文标题与空正文列为正式审查门禁;当前等待用户授权选择干净替代分支/新 PR,或重写现有 PR 并 force-push。 -- [ ] S9:全部完成后,将稳定结论保留在权威文档/共享记忆中,并在最终代码提交中删除本临时计划文件。 - -执行纪律:一次只推进一个步骤;任何步骤发现合同歧义、公开 API 变化、schema 变化、历史重写或真实付费请求需求时立即暂停,不跨过确认门。每次交接必须在本节勾选真实完成项,并在“实施记录”写入提交、测试和剩余风险;不得预先勾选。 - -## 五、预计文件范围 - -核心实现: - -- `apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs` -- `apps/ai-game-creator-shell/src-tauri/src/project/asset_canvas/generation.rs` -- `apps/ai-game-creator-shell/src-tauri/src/agent/generation/external_generation_state.rs`(仅提取共享服务身份纯逻辑时) -- `apps/ai-game-creator-shell/src/features/asset-canvas/AssetCanvasSurface.tsx` -- `apps/ai-game-creator-shell/src/features/asset-canvas/assetCanvasSurface.css` -- `apps/ai-game-creator-shell/src/view/project-development/index.tsx` -- `apps/ai-game-creator-shell/src/styles.css`(仅恢复面板确有布局需要时) -- `packages/image-canvas-core/src/selection.ts` -- `packages/image-canvas-core/src/stageInteractions.ts` -- `packages/image-canvas-react/src/useImageCanvasStageInteractions.ts`(优先复用,不随意改行为) - -测试: - -- `apps/ai-game-creator-shell/tests/assetCanvasSurface.test.tsx` -- `apps/ai-game-creator-shell/tests/projectResourceLiveIntegration.test.tsx` -- `packages/image-canvas-core/src/sharedCanvasCore.test.ts` -- `packages/image-canvas-react/src/sharedCanvasReact.test.tsx` -- `resource_editor.rs` 与 `asset_canvas/generation.rs` 内 Rust 定向测试 - -文档: - -- `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` -- `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` -- `docs/project-memory/shared-memory/decision-log.md` -- `docs/project-memory/shared-memory/pitfalls.md` -- 本计划文件(仅在全部完成时删除) - -实际实施可以减少文件,但增加范围前必须说明必要性;禁止借机重构无关 Runtime、主站编辑器、后端生成队列或 SpacetimeDB。 - -## 六、验证矩阵 - -### 6.1 Rust 定向验证 - -```bash -cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml resource_editor -- --test-threads=1 -cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml asset_canvas -- --test-threads=1 -cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --tests -``` - -定向 filter 必须真实匹配新增用例;`0 tests` 不算通过。必要时按新增测试统一前缀再拆分运行,避免把无关长测当成唯一证据。 - -### 6.2 前端与共享画布验证 - -```bash -npm run test -- apps/ai-game-creator-shell/tests/assetCanvasSurface.test.tsx apps/ai-game-creator-shell/tests/projectResourceLiveIntegration.test.tsx packages/image-canvas-core/src/sharedCanvasCore.test.ts packages/image-canvas-react/src/sharedCanvasReact.test.tsx -npm run ai-game-creator-shell:typecheck -``` - -需要真实 DOM 行为的恢复面板补充键盘焦点、Escape、按钮可访问名称和窄容器测试;不通过默认说明文案填充 UI。 - -### 6.3 仓库门禁 - -```bash -npm run check:encoding -git diff --check -``` - -本轮按用户授权以改动范围内的定向测试为主,不把完整 `npm run check:native-shells` 作为每阶段或最终强制项。若定向 Rust、前端测试、typecheck 或差异复核暴露跨模块风险,再升级运行相关完整门禁;sandbox loopback `EPERM`、外部依赖失败和源码测试失败分别报告,不能互相冒充。 - -### 6.4 安全与差异复核 - -- `git status --short` 中用户原有 `.env`、`.env.local`、`output/manual-validation/` 保持未暂存、未修改归属。 -- 私有 ledger 序列化测试扫描 Key、Authorization、ticket、签名 URL、Provider 正文、绝对路径和敏感字段名,命中数必须为 0。 -- `git diff --check`、中文编码检查和冲突 marker 扫描通过。 -- 若没有修改 External v1 公开契约,OpenAPI 必须保持零 diff;若出现 diff,任务自动回到契约评审门。 - -### 6.5 远端验收 - -- Gitea 精确 head 的四个 required job 全部成功。 -- 逐条回复 R1-R9 对应审查意见,提供代码与测试证据。 -- PR 不落后最新 base,且最终提交历史满足仓库中文标题和逐行正文规范。 - -## 七、完成定义与计划删除条件 - -只有以下条件全部同时满足,才允许删除本文: - -- R0-R9 全部实现或按明确批准的替代方案闭环,没有保留“后续再修”的 P1/P2。 -- 故障矩阵、乱序回包、Key 已失效迁移、可选恢复队列、失败分类、共享 Shift 选择和零位移 history 回归全部通过。 -- 最新 master 已融合,冲突按权威合同解决,分支不落后 base。 -- AI 游戏创作技术方案、工作台 PRD、decision log 和 pitfalls 已更新为当前真实实现,不保留过期承诺。 -- 定向 Rust、前端、typecheck、encoding 和 diff 门禁有可信结果;若定向结果要求升级,则对应完整 native-shell 门禁也有可信结果;远端四项 required CI 在精确最终 head 上全部成功。 -- 提交历史和 PR 审查闭环;任何 force-push/替代分支选择均已取得用户授权并完成。 -- `.env`、`.env.local`、`output/manual-validation/` 和其它用户本地文件未进入任何提交。 - -删除方式:在最后一个工程提交中删除本文,不留下“计划曾存在/已删除”的墓碑注释或墓碑文档;长期有效的结论只保留在权威技术文档、decision log 和 pitfalls 中。若任一条件未满足,本文继续保留并更新状态,不得为了让 diff 看起来完成而提前删除。 - -## 八、实施记录 - -- `2026-08-11`:通过 `tea` 只读核对 PR #136:远端 head 仍为 `9ff16393e0`,旧 head 四项 required CI 全绿但 review #210 / #212 保持请求修改;其中代码意见对应的草稿单调 revision、远端终态失败、可选恢复队列、资产/版本 crash journal、旧 Key 显式迁移、Shift/零位移和失败分类均已在本地闭环。当前 Gitea workflow 不含全历史提交标题检查,但审查者明确要求整理 `9ff16393e0`、`08a96e251c`、`c24e3010f8`、`b95da30721` 的英文标题/空正文和 `0b6be155dd` 的空正文;普通快进推送不能关闭该审查意见。S8 因此等待用户在“从最新 master 建干净替代分支并开新 PR(推荐)”与“重写现有 PR 历史并 force-push”之间明确授权,未授权前不推送、不改写远端。 -- `2026-08-11`:融合后定向验证与独立只读审查完成。无限画布前端四文件 `65/65`、`resource_editor 31/31`、`asset_canvas 27/27` 通过;主线完美像素 `useImageCanvasGenerationWorkflow 104/104`、`platform-image 2/2`、`api-server 4/4` 通过。客户端 typecheck、`cargo check --tests`、`cargo fmt --check`、Prettier、编码检查与 merge diff 检查通过。独立审查确认 `origin/master 3c457feb4` 为当前 HEAD 祖先,无冲突标记或 P1/P2/P3;共享记忆同时保留完美像素逻辑分辨率与 Tauri 恢复/非破坏编辑合同,External v1 OpenAPI 和相关 Skill 与主线完全一致。S8 现在只剩远端分支/提交历史方案、push、精确 head required CI 与远端审查闭环。 -- `2026-08-11`:本轮修复已提交为 `ca59fa496`(中文标题、逐行正文),提交只包含显式任务文件;`.env`、`.env.local`、`output/manual-validation/` 仍未进入提交。首次尝试融合 `origin/master 3c457feb4` 时权限审批服务在命令执行前返回 `503 auth_unavailable`;用户随后明确授权重试,已通过中文标题与逐行正文的 merge commit `c8c0c6deeb42278635736c7825781bfd32b963a4` 成功融合,分支相对主线为 `ahead 67 / behind 0`。Git 自动合并共享记忆和后端文件,无冲突;S8 继续等待融合后验证、远端 required CI 与提交历史方案闭环。 -- `2026-08-11`:S7 完成。最终组合验证为前端四文件 `65/65`、`resource_editor 31/31`、此前未受后续改动影响的 `asset_canvas 27/27`;客户端 typecheck、`cargo check --tests`、`cargo fmt --check`、Prettier 改动文件检查、`npm run check:encoding`(`5383` 个文件)和 `git diff --check` 均通过。新增行扫描未命中私钥、长 Bearer/API token、签名 URL、个人绝对路径或冲突 marker;本任务对 External v1 OpenAPI 仍为零 diff;`.env`、`.env.local`、`output/manual-validation/` 保持未暂存并明确排除。S8/S9 仍等待本轮提交、最新 `origin/master 3c457feb4` 融合、精确最终 head 远端 required CI 以及提交历史方案确认,因此计划继续保留。 -- `2026-08-11`:第二轮恢复面板复核发现 3 个 P2 并已闭环:并发 operation 的原始动作错误使用逐 operation 状态保存,不再因其它 operation 推进全局读取 epoch 而丢失;焦点陷阱把动态禁用后已退出当前可聚焦集合的 active element 视为边界;modal 打开/关闭 epoch 阻止同项目旧 action 关闭后来重开的新面板。新增 3 条真实异步交互回归后资源实时集成测试为 `17/17`,四文件前端组合定向为 `65/65`(Surface `40`、资源实时集成 `17`、core `5`、React `3`),客户端 typecheck 与 Prettier 改动文件检查通过。 -- `2026-08-11`:Rust 最终缺口回归补齐:旧 `Committed` version journal 即使项目 revision 仍停在 base 也必须进入对账;External `202` 非法 JSON 或缺 operationId 均原子转为 `reconciliation-required`,后续 resume 在网络前失败关闭。精确非 loopback 用例 `1/1` 通过;202 mock 在沙箱内因 `bind EPERM` 失败,允许 loopback 后 `1/1` 通过;最终 `resource_editor 31/31`、`cargo check --tests` 和 `cargo fmt --check` 通过。仓库编码检查继续为 `5383` 个文件通过。 -- `2026-08-11`:首次 S7 定向门禁全绿后继续执行三路独立只读审查,没有提前提交。审查未发现前端 P1 或锁顺序/网络持锁问题,但发现 1 个 Rust P1:旧 `Committed` version journal 缺 revision 证明字段时仍可绕过门禁;另发现 8 个 P2:committed 正式媒体为 symlink/目录/读取异常时未转对账、External v1 明确 HTTP 400 仍允许重放 POST、progress 首次读取失败后同 revision 无法重试、pan/move/resize 拖离再回原点未恢复初始快照、恢复/归档后的权威重读迟到污染、项目切换存在 render 到 effect 的守卫窗口、恢复失败未重读权威队列、全局锁阻塞其它 operation。modal 缺少 focus trap 的合同偏差一并修复。S2、S4、S5 已据实重新打开,三个子代理按 Rust、画布、恢复面板互斥文件范围并行补实现与回归。 -- `2026-08-11`:S6 完成。AI 游戏创作技术方案、项目开发工作台 PRD、decision log 和 pitfalls 已同步为当前实现:补充 committed 后 staging 只在正式媒体摘要和 manifest 唯一精确 asset 均可证明时清理,清理 I/O 失败不逆转 durable committed;正式身份、媒体或 manifest 漂移时保留现场并进入 `reconciliation-required`。version journal 现在冻结 project revision before/after 身份与 after 快照;manifest 已有子版本但缺 journal、旧 journal 无法证明 revision 推进或 revision 已越界时均失败关闭,不再猜测 committed。 -- `2026-08-11`:S7 本地验证已运行,等待最终独立差异审查后再勾选。Rust `resource_editor 27/27`、`asset_canvas 27/27` 通过;两组 loopback 测试在沙箱分别有 `3` 与 `5` 个 `bind EPERM`,放宽 loopback 后全部通过。`cargo check --tests`、`cargo fmt --check`、四文件前端定向测试 `54/54`(Surface `36`、资源实时集成 `10`、core `5`、React `3`)、客户端 typecheck、`npm run check:encoding`(`5383` 个文件)、`git diff --check`、冲突标记扫描和 External v1 OpenAPI 零 diff 均通过。安全差异扫描未在新增行发现个人绝对路径、私钥或长 Bearer 形态;`.env`、`.env.local`、`output/manual-validation/` 仍未进入任务差异范围。 -- `2026-08-11`:S5 完成。工作台顶部恢复按钮改为打开独立面板,面板显示后端权威队列中每个 operation 的安全名称、编辑类型、创建时间和阶段;可恢复项可任意选择,`remote-failed` 只能显式移出活动队列,`reconciliation-required` 始终只读。列表读取失败保留错误并提供重试,不再伪装成空队列;操作后重读后端队列,项目切换后的迟到恢复结果由 flow/path 双重守卫丢弃。面板支持 Escape、初始关闭按钮聚焦、关闭后聚焦归还,桌面最大高度内滚动且小于 620px 时行动作改为竖排全宽。画布失败态增加 `generation / draft-save / asset-commit / recovery / cancellation` 稳定操作分类与纯展示映射,只有 generation 失败显示“返回修改/重新确认”,保存、CAS、提交、恢复和取消故障均不会引导新生成。定向验证:Surface `33/33`、资源实时集成 `8/8`、TypeScript typecheck 和 `git diff --check` 通过。 -- `2026-08-11`:S4 完成。generation progress 不再用浅拷贝先行抬高草稿 revision,而是记录已观测的最高 revision,并在 `loadDraft` 回包当下同时核对 scope 身份、最低期望 revision 和当前草稿 revision;草稿保存队列与生成/提交回包共用同一单调落地门禁。Tauri 的指针与键盘选择统一调用 core `resolveLayerPointerSelection`,Shift 单选自身不再清空,普通点击已选图层保留多选拖动集合。图层移动、缩放与背景平移改为首次真实变化时只 capture 一次冻结 history,pointerup 仅在几何或选择确实变化时 mark dirty,零位移不生成撤销、documentVersion 或草稿保存。定向验证:core `5/5`、React lifecycle `3/3`、Tauri Surface `31/31`、TypeScript typecheck 和 `git diff --check` 通过。 -- `2026-08-11`:S3 完成。新生成账本固定写入 `service-origin-v1`,资源编辑与素材画布复用同一服务身份分类;可用当前 Key 验证的旧账本自动迁移,无法验证的旧远程事实在确认前零网络并使用 10 分钟、绑定原 operation 冻结事实的挑战值。确认命令不接收 Key、base URL 或请求正文,在 generation singleflight lock 与 project write lock 内重读配置和账本;accepted/running 只 GET 原 operation,prepared 只使用冻结 endpoint、字节和幂等键重放一次原 POST。前端新增独立身份确认对话框。最终定向验证:`assetCanvasSurface.test.tsx` `27/27`、TypeScript typecheck 通过、共享身份分类 `1/1`、服务身份 loopback 回归 `4/4`;后者在沙箱因 `bind EPERM` 受阻,允许 loopback 后全部通过。账本和前端 DTO 的回归确认不含凭据。 - -- `2026-08-11`:完成只读基线核对和源码定位,冻结 R0-R9 计划。尚未融合 master、尚未修改生产代码、尚未运行修复后测试;用户本地 `.env`、`.env.local`、`output/manual-validation/` 保持原状。 -- `2026-08-11`:用户授权开始按计划修复,并明确允许以改动代码范围的定向测试为主;已据此调整 S7 和验证矩阵,完整 `check:native-shells` 仅在定向结果提示跨模块风险时升级执行。 -- `2026-08-11`:S0 完成。远端审查分支确认为 `9ff16393e0ccc65f3e14244a86cf8516723c3e37`,本地先从 `d6abd2a1fc606e35d2dbb0420c712d6d5a4bcf70` 安全快进;随后两次 fetch 确认最新 `origin/master` 为 `aa5c857060af4fe2644b21e0679a727490995935`。用户本地 `.env`、`.env.local`、`output/manual-validation/` 未修改归属、未暂存。 -- `2026-08-11`:S1 完成。通过 `f389716149f04feae9ac1e771fa5cd7e347af4eb` 与 `fa2d8be29a5c6098008797d16360af42fcecdf4a` 融合最新主线;按双方合同合并 `Cargo.lock`、工作台 PRD 与技术方案,并修复自动合并暴露的 Godot `projectRevision` 缺失和 Vite `resolve` 重复。`npm run ai-game-creator-shell:typecheck`、客户端 HTTP/错误边界 `5` 项定向测试、`cargo metadata --locked --no-deps`、`npm run check:encoding`、冲突扫描和 `git diff --check` 通过。 -- `2026-08-11`:S2 完成。资源编辑账本新增 `remote-failed / archived` 持久终态、稳定失败分类和显式归档命令;远端明确失败后恢复入口在任何网络动作前失败关闭,只有该终态可移出活动队列,`result-unknown / reconciliation-required` 不可归档。资产提交改为 `prepared -> media-installed -> manifest-written -> revision-written -> committed` durable journal,冻结文件、manifest before/after 与 project revision before/after 身份;5 个崩溃断点均可前向恢复,漂移进入对账。审计发现的任务图片正规化同类 manifest/revision 窗口也复用资产事务日志,并覆盖旧实现“manifest 已写、revision 未写”的恢复。沙箱内 3 个 loopback fixture 因 `bind EPERM` 失败,提升权限重跑后资源编辑 `19/19` 通过;新增正规化恢复 `2/2` 通过。