将资源依赖图计算迁移到Rust
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / Backend tests (pull_request) Failing after 7s
Project CI / Frontend tests (pull_request) Successful in 2m50s
Project CI / Native shell tests (pull_request) Successful in 11m33s

新增只读资源依赖图模型,完成过滤、去重、环检测和任务流聚合
前端SVG仅负责几何渲染、搜索联动、选中高亮和拖动预览
补充资源图、覆盖层和工作台回归测试
同步更新工作台PRD、技术方案与项目记忆
This commit is contained in:
2026-07-31 19:09:57 +08:00
parent f582ecf032
commit 29dce59b35
14 changed files with 1874 additions and 558 deletions
@@ -16,13 +16,15 @@
---
## 2026-07-31 AI 游戏创作资源依赖图采用前端派生 SVG
## 2026-07-31 AI 游戏创作资源依赖图采用 Rust 只读拓扑与前端派生 SVG
- 背景:资源画布已有 dependency / type 双模式坐标与本地 CAS sidecar,但 dependency 模式尚未把当前 manifest 中可证明的资源引用和任务流转可视化;关系图不能反向污染布局持久化或建立第二套资源真相。
- 决策:dependency 模式从当前资源卡投影与 manifest task 派生 `ProjectResourceGraph`,使用原生 SVG 底层图层渲染。资产 `source.referenceResourceIds` 只在唯一匹配另一资产 `source.resourceId` 后形成橙色实线;任务依赖按任务对聚合为灰色虚线主线与两端分支,禁止资源笛卡尔积。图模型以迭代式强连通分量分析识别资源环和完整任务 DAG 环;搜索、选择、拖动只改变当前图层几何和高亮
- 生命周期与边界:type 模式不挂载图层;切换 mode、项目或卸载工作台时销毁 SVG、ResizeObserver 和窗口监听。SVG 统一 `pointer-events: none`,不干扰卡片点击/拖动;path、marker、图结构和 section 原点从不持久化。本切片不修改 Rust、Tauri command、layout sidecar、`resourceCanvasLayoutModel.ts`、manifest、api-server 或 SpacetimeDB,也不引入第三方图表库
- 影响范围:`apps/ai-game-creator-shell` 项目开发资源投影、依赖图模型、SVG overlay、样式与前端测试,以及工作台 PRD 和客户端实施计划
- 验证方式:图模型与 SVG 定向测试覆盖去重、无效 ID、完整任务环、可见资源自引用闭环、任务流聚合、搜索过滤、选择高亮和拖动几何;AppSurface 覆盖两种边、type 模式卸载和项目切换销毁,并运行 shell typecheck、编码检查与 `git diff --check`
- 决策:dependency 模式由 Tauri Rust 只读命令从当前 manifest、资源卡身份和有界 `.agent/agent.db` 审计构建稳定 `ProjectResourceGraph` read model,前端只归一化 DTO、测量卡片坐标并用原生 SVG 渲染。资产 `source.referenceResourceIds` 只在唯一匹配另一资产 `source.resourceId` 后形成橙色实线;任务依赖按任务对聚合为灰色虚线主线与两端分支,禁止资源笛卡尔积。Rust 以迭代式强连通分量分析识别资源环和完整任务 DAG 环,并返回资源局部连接索引
- 任务身份:External Editor 响应中的 `source.taskId` 是平台生成任务 ID,不等于本地 manifest task ID,禁止据此分配 producer。画布资产只接受 `agent.runtime.canvas.asset_generate` 审计中经当前 manifest task 校验的 `assetId -> agentId`;证据缺失、冲突或已超出有界读取窗口时不生成对应 task flow。任务产物与 Agent 回执继续使用自身已有的 manifest task 身份
- 生命周期与边界:Pointer Move 先用 `requestAnimationFrame` 合帧;基础 positions 与拖动预览分离,SVG 静态拓扑保持复用,每帧只按局部索引更新拖动资源关联的 reference edge 和 task flow。`ResizeObserver` 在单个图层生命周期只创建一次。type 模式不挂载图层;切换 mode、项目或卸载工作台时销毁 SVG、Observer 和窗口监听。SVG 统一 `pointer-events: none`path、marker、图结构和 section 原点从不持久化
- 数据边界:本切片只新增 Tauri Rust 只读 read model,不修改 layout sidecar、`resourceCanvasLayoutModel.ts`、manifest、api-server、SpacetimeDB schema 或生成绑定,也不引入第三方图表库。dependency section 只在显示层额外预留 `64px` 右侧视觉 gutter,卡片坐标和持久化布局不变
- 影响范围:`apps/ai-game-creator-shell` 的 Tauri project read model/command、项目开发资源投影、依赖图 DTO、SVG overlay、样式与前后端测试,以及工作台 PRD 和客户端实施计划。
- 验证方式:Rust 定向测试覆盖真实 producer 映射、拒绝复用外部 `taskId`、证据缺失、去重、无效 ID、完整任务环、4096 任务链与聚合复杂度;前端模型和 SVG 测试覆盖 DTO 防御过滤、局部上下游、可见资源自引用闭环、搜索、高亮、单帧局部 path 更新和稳定 ObserverAppSurface 覆盖生产数据形状、两种边、type 模式卸载和项目切换销毁,并运行 shell typecheck、编码检查与 `git diff --check`
- 关联文档:`docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md``docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
---
@@ -14,6 +14,14 @@
- 关联:相关文件、文档、提交或 Issue
```
## External Editor taskId 不能当作本地 manifest taskId
- 现象:画布资产之间已有橙色精确引用线,但依赖任务之间没有灰色 task flow;测试用 `design-foundation` 之类字符串时正常,真实生成返回 `task-1` 后失败。
- 原因:`GameCreationAppAssetSource.taskId` 保存的是 External Editor 生成任务身份,命名空间与本地 `.agent/manifest.json` 的 Agent/task 身份不同;前端用 `taskById.get(source.taskId)` 会让真实画布资产全部失去 producer。
- 处理:资源依赖图的 Tauri Rust read model 从有界 `.agent/agent.db` 读取 `agent.runtime.canvas.asset_generate`,以 `assetId -> agentId` 映射 producer,并要求 `agentId` 存在于当前 manifest。记录缺失、多个不同有效 Agent 冲突或读取已截断时失败关闭该资产的 task flow,不回退 `source.taskId`。精确 `asset-reference` 仍只依赖 manifest 中外部 resourceId 的唯一匹配。
- 验证:Rust fixture 把 `source.taskId` 固定为 `task-1 / task-2`,只有审计提供 `art-director / design-foundation` 后才生成 task flow;移除审计后橙色引用保留、灰色任务流消失。AppSurface 使用相同生产数据形状回归。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/project/resource_dependency_graph.rs``apps/ai-game-creator-shell/src/view/project-development/resourceDependencyGraphModel.ts``docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
## Jenkins 异步备份不能用 nohup 脱离作业
- 现象:Stdb Publish 成功,上传日志只留下“已获取进程锁 / 上传已有备份 / 目标对象”,没有成功或可捕获错误;本地 tar.gz 和 `uploadStatus=deferred` manifest 每次发布后继续增长。