记录 AGC 资源画布「手动整理」口径变更

- decision-log:追加 2026-09-14 条目,记录默认 preserve、显式「整理画布」、
  依赖侧关系图首次就绪的一次性重派生、新素材按 manifest 新增 id 聚焦四条决策与变异验证
- pitfalls:追加「不要恢复无条件重派生」条目,含 changed 门、ready 时序、
  项目作用域 flag 与新素材基线四个易错点
This commit is contained in:
2026-09-14 17:08:00 +08:00
parent d02d0ed7a4
commit 3b8ecb02d4
2 changed files with 19 additions and 0 deletions
@@ -3,6 +3,16 @@
> 用途:记录已经确认、会影响后续开发的长期技术/产品/协作决策。短期讨论不要写在这里。
> 当前口径:历史条目的旧路径、旧版本和已退役对象只用于追溯,不构成现行实现依据;如与当前代码或 `docs/README.md` 冲突,以当前代码和最新专题文档为准。
## 2026-09-14 AGC 资源画布改为「手动整理」:新素材不再自动重排,整张重排只由「整理画布」发起
- 背景:生成一张新素材会让整张资源画布重排。两个 layout hook 都把 `rederiveAutomaticPositions` 打开(type 侧无条件 `true`dependency 侧长期等于 `resourceGraphReady`),而该开关的语义是「每次资源协调签名变化就丢掉全部 `manuallyPlaced=false` 坐标、按当前资源与拓扑整体重算」;新增一张素材必然改签名,于是既有自动卡全部跟着挪位,用户刚记住的位置就没了。画布上也没有任何显式整理入口(`复位资源视图` 只复位视口)。
- 决策一(默认口径):两个 mode 的 `rederiveAutomaticPositions` 固定 `false`——画布默认只补新卡,不动任何既有坐标(`preserve`)。整张重排改为显式动作:依赖/类型 tab 组新增「整理画布」按钮,调用 hook 新暴露的 `rederiveNow()`,复用既有写队列与 sidecar 写回链路,只把策略换成 `rederive`;用户可见反馈继续用既有 `resourceLayoutNotice`(成功即「布局已保存」)与 `resourceLayoutSaving`,不新增状态位。重算结果与当前坐标一致时**不落盘**(沿用既有 `changed` 门):已经整齐的画布按一下不该白推进一次 CAS / revision,关系图 `producerMappingTruncated` 时更不该把一份来自不完整关系图的自动布局写进 sidecar——既有用例 `keeps trusted truncated-graph depths through the workbench without persisting a flat automatic layout` 就是钉这条。
- 决策二(依赖图首次就绪的那一次):`dependencyDepth` 仍要在关系图就绪后按最终拓扑排一次列。这一层不再靠「让布尔长期为真」,而是按**项目作用域的一次性 flag**(`dependencyRederiveScopeRef`):关系图就绪且该侧 sidecar `ready` 的那一刻调用一次 `rederiveNow()`,之后一律 `preserve`;切排序 tab 不重新武装,切项目才重新记一次。
- 决策三(生成后自动聚焦):新增 `seenManifestAssetIdsRef` + effect,按 `manifest.assets` 的**新增 id**(不是 diff 位置、也不是文件名)把新卡交给既有 `pendingResourceFocusRef` + `advanceFocusGeneration()` 裁决链。首次打开项目 / 切项目只登记基线、不聚焦;重命名不改 id、天然不触发;已有指向同一资源的聚焦意图时不重复挂(显式生成链路在提交时就已挂好)。被搜索条件挡住时继续复用既有的「清除搜索并定位」提示与动作。
- 影响范围:`apps/ai-game-creator-shell/src/view/project-development/useProjectResourceCanvasLayout.ts`(写意图增 `rederive` 标记、写策略分支、`rederiveNow`)、`.../index.tsx`(两个 hook 配置 + 一次性重派生 effect + 新素材聚焦 effect + 「整理画布」按钮)、`apps/ai-game-creator-shell/tests/resourceCanvasManualLayout.test.tsx`。不改 `manuallyPlaced` 语义、不改 sidecar 的 CAS / revision 协议与字段形状、不改卡片尺寸模型、不改「搜索不重排」合同、不改 Rust 资源图与 `dependencyDepth` 权威。
- 验证方式:新增 `resourceCanvasManualLayout.test.tsx` 8 条:新素材入库后除新卡外坐标逐值不变、依赖侧首次就绪重算一次后同样不再重排、新素材自动聚焦、被搜索挡住走既有提示与动作、「整理画布」按 `rederive` 重算并保留手动坐标且给出一次可见反馈、已经整齐时再按一次不产生第二次落盘、首次打开与切项目都不聚焦。变异验证(均已实测):① type 侧改回 `true`、dependency 侧改回 `resourceGraphReady` → 3 条红;② 去掉新素材基线的首次登记 → 3 条红(既有卡被当成"刚生成"选中);③ 去掉 hook 里的 `rederive` 写策略分支 → 3 条红;④ 把显式整理改成强制写回(去掉 `changed` 门)→ 既有「截断关系图」用例红。
- 关联文档:[踩坑记录](pitfalls.md)、[项目开发工作台 PRD](../../prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md)。
## 2026-09-14 客户端 CI 按门禁组拆成三个 jobAGC 的 web / rust 两段并行
- 背景:`Project CI / Native shell tests` 把微信壳、Expo 移动壳、Tauri 桌面壳、H5 HostBridge 与 AI 游戏创作壳的全部门禁串在一个 job 里,实测 18 分 37 秒;同一次运行的 Repository / Frontend / Backend 分别只要 3 分 21 秒、4 分 16 秒、6 分 14 秒,其余三个 job 结束后客户端 job 还要再跑十几分钟。日志时间戳显示门禁段 932 秒里:AGC `ai-game-creator-shell:check` 占 654 秒(其中壳内 Rust 套件 2451 个用例 `--test-threads=1` 单跑 441.58 秒、编译 79 秒),AGC vitest 75 秒,两个发布构建 smoke 加落盘断言 230 秒,而 h5 / 微信 / 移动 / 桌面壳的全部运行时门禁加起来不到 50 秒。
@@ -1,5 +1,14 @@
# 踩坑与排障记录
## 2026-09-14 AGC 资源画布不要恢复「无条件重派生」,否则新增一张素材就整张重排
- **现象**:用户生成一张新素材后,画布上既有卡片全部移位,刚摆好的位置失效。
- **原因**`useProjectResourceCanvasLayout``rederiveAutomaticPositions=true` 会让**每一次资源协调签名变化**(新增 / 删除素材、改标签、改分类、拓扑签名变化)都丢掉全部 `manuallyPlaced=false` 坐标整体重算。签名里必然包含新素材,所以「新增一张素材」就等于「整张画布重排」;两个 hook 当时都开着它(type 侧无条件 `true`dependency 侧长期等于 `resourceGraphReady`)。
- **处理(现行口径)**:默认一律 `preserve`(只补新卡)。整张重排只由「整理画布」按钮调用 hook 的 `rederiveNow()` 发起,或由「关系图首次就绪」那一次按项目作用域的一次性 flag 发起。**不要**把 `rederiveAutomaticPositions` 改回长期 `true` / `resourceGraphReady`,也不要为「拓扑变了要立刻重排」再加自动触发点——那正是本条要修掉的行为。
- **易错点**:① 一致性判据是 `reconcileResourceCanvasLayout` 输出里**每个分区按 `(y, x, resourceId)` 排序**后的数组与来源逐项比较,所以手工构造 sidecar 夹具时要按同序写,否则会被判成「变了」而多写一次,用例里会看到意料之外的写回;② 关系图首次就绪那一次重算要等该侧 sidecar `ready` 之后再发(关系图可能先就绪),否则这一次会被吃掉;③ 依赖侧的一次性 flag 按**项目作用域**记账,不要挂到 `resourceGraphReady` 这类会随排序 tab 反复翻转的值上,否则每次切回依赖视图都会重排一次;④ 新素材聚焦按 `manifest.assets` 的新增 id 判定,首次打开 / 切项目必须先登记基线,否则一进工作台就跳到最后的卡上;⑤ 不要为了让「整理画布」按钮"一定有反馈"而把 `changed` 门拿掉——重算结果与当前坐标一致时不写盘是既有合同,关系图 `producerMappingTruncated` 时强行写回等于把一份来自不完整关系图的自动布局持久化(`appSurface.test.ts``keeps trusted truncated-graph depths through the workbench without persisting a flat automatic layout` 会红)。
- **验证**`npx vitest run apps/ai-game-creator-shell/tests/resourceCanvasManualLayout.test.tsx`(8 条);把两个 hook 配置改回旧口径会红 3 条。
- **关联**`apps/ai-game-creator-shell/src/view/project-development/useProjectResourceCanvasLayout.ts``apps/ai-game-creator-shell/src/view/project-development/index.tsx`
## 2026-09-14 客户端 CI 拆分后,选组运行会跳过未选分组,且必须同步分支保护
- **现象**:把 `Native shell tests` 拆成客户端三个 job 后,如果只跑 `npm run check:native-shells:release`,静态契约和壳运行时门禁都不会执行;如果只跑 `--groups=contract``desktop-release-binary-artifact` 又会因为缺少 `build/native/desktop/` 产物而失败。