Merge remote-tracking branch 'origin/master' into HEAD
Project CI / Repository checks (pull_request) Successful in 4m11s
Project CI / Frontend tests (pull_request) Successful in 4m35s
Project CI / Backend tests (pull_request) Successful in 5m38s
Project CI / Native shell tests (pull_request) Successful in 12m14s

This commit is contained in:
2026-08-26 16:03:24 +08:00
20 changed files with 300 additions and 64 deletions
@@ -55,3 +55,7 @@
2. 确认没有密钥、`.env`、Cookie、日志、缓存、数据库 dump、构建产物或个人路径。
3. 确认相关当前文档与共享记忆已同步,且 docs 入口没有指向已删除或退役实现依据。
4. 提交标题使用中文,标题后逐行写明本次变更。
## Gitea CI 依赖闭合
`.gitea/workflows/project-ci.yml` 的 `Native shell tests` 在运行原生壳门禁前,必须使用 `cargo fetch --locked` 预取 `server-rs/Cargo.toml`、桌面壳和 AGC 壳三份依赖。AGC 壳检查还会运行 `platform-llm` 与 `shared-contracts` 的 server-rs workspace 测试,这些命令以及 AGC 壳测试必须带 `--locked`,避免在测试阶段重新解析 registry index;锁文件发生变化时应先更新受信任 CI 镜像缓存,再重跑门禁。
@@ -4939,3 +4939,10 @@
- 严格图集崩溃补充:规范图和背景图的两文件 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 无界增长。
## Native shell CI 不能在测试阶段重新解析 Cargo registry(2026-08-26)
- 现象:原生壳 job 的依赖预取成功后,AGC 检查仍在 `platform-llm` 测试阶段重新更新 registry index,并因 `symphonia` 下载的 TLS EOF 失败。
- 原因:native job 没有显式预取 `server-rs/Cargo.toml`;`ai-game-creator-shell:check` 的 server-rs workspace 命令没有 `--locked`。
- 处理:native job 预取 server-rs、桌面壳和 AGC 壳三份 lockfile;`platform-llm`、`shared-contracts` 与 AGC 壳测试统一使用 `--locked`,不降低原生测试门禁。
- 验证:workflow 回归测试、锁定的 Rust 测试和原生壳门禁均需运行;若本地 EAS CLI 版本漂移,应单独报告环境阻塞,不把它误判为本次 Cargo CI 修复失败。
@@ -83,14 +83,14 @@
## 操作边界
- 栏目顺序固定为 `设计文档 -> 美术资源 -> 音乐音效 -> 游戏代码 -> 项目版本`。完全空项目显示全部栏目的分区展览;任一栏目出现资源后,分页大纲以左侧垂直居中的悬浮 Dock 展示全部栏目。常态缩小、降低不透明度并移除容器与选中项背景,只露出栏目文字;悬停或键盘聚焦时平滑恢复完整尺寸,显示栏目图标、Dock 背景和选中态视觉强调。默认停留在该顺序中的第一个非空栏目,空栏目仍可打开空画布。
- 普通滚轮向下切到下一栏目、向上切到上一栏目并循环;持续滚动时将离散切页意图加入有界队列,浏览器合并形成的单个大幅滚轮事件也要按输入强度拆分为多个切页意图。同一节流窗口内的待处理步数必须合并为一次目标栏目切换,不能逐页挂载并加载中间栏目的资源,以免资源渲染阻塞后续滚轮输入;同时限制切页频率和最长排队距离,避免触控板惯性长时间自动翻页。点击大纲、底部“下一页”标题或自动定位资源属于显式切页,必须先取消尚未执行的滚轮队列,不能在显式切页后继续跳转;开始拖动画布或资源卡时也必须取消待处理切页,切页前必须终止旧栏目的画布拖动和 pointer capture,避免旧 viewport 写入新栏目。
- 普通滚轮向下切到下一栏目、向上切到上一栏目并循环;持续滚动时将离散切页意图加入有界队列,浏览器合并形成的单个大幅滚轮事件也要按输入强度拆分为多个切页意图。同一节流窗口内的待处理步数必须合并为一次目标栏目切换,不能逐页挂载并加载中间栏目的资源,以免资源渲染阻塞后续滚轮输入;逻辑目标栏目在事件处理中同步推进,可见栏目和 viewport 通过 React transition 异步提交,渲染尚未完成时到达的新滚轮仍基于最新逻辑目标继续计算,渲染过程不得把目标栏目回写成旧页面。同时限制切页频率和最长排队距离,避免触控板惯性长时间自动翻页。点击大纲、底部“下一页”标题或自动定位资源属于显式切页,必须先取消尚未执行的滚轮队列,不能在显式切页后继续跳转;Ctrl/Meta 缩放、触控板缩放手势、排序切换和开始拖动画布或资源卡也必须取消待处理切页,缩放后的下一次普通滚轮应立即建立新的翻页意图。切页前必须终止旧栏目的画布拖动和 pointer capture,避免旧 viewport 写入新栏目。
- 每种排序模式下的每个栏目画布都保留独立 viewport;首次进入该“排序模式 + 栏目”组合时按当前内容适配视口,离开后再返回则恢复该组合上次的平移和缩放。空白处拖拽平移画布,资源卡拖拽移动卡片并更新依赖线,Ctrl/Meta 缩放只作用于当前组合,不能牵动其它排序模式或栏目。
- 依赖画布复用 `@genarrative/image-canvas-core` 的 viewport 计算,并复用现有资源卡片、布局和依赖连线模型。
- 非空状态不使用资源分区滚动条、分区缩放或分区高度操作作为主要导航;栏目通过大纲、底部下一页标题和滚轮切换。
- 当前栏目画布背景是无限的:用户可以将 viewport 沿 x/y 任意方向平移,画布不以资源 extent 作为导航边界,也不显示可见画布边缘。资源卡片的持久化布局坐标允许落在 `-1_000_000..=1_000_000`,用于支撑元素位于世界原点左上方;超出该范围仍拒绝写入,避免持久化非法布局。这与 viewport 能否继续平移是两层独立语义。搜索、详情卡和临时隐藏不得改变 viewport。
- 普通滚轮切换栏目,指针拖动空白平移画布,Ctrl/Meta 缩放、复位以及容器 resize 后都必须保持同一套 viewport 数据流。只有“排序模式 + 栏目”组合首次获得可测量容器尺寸或用户显式复位时才重新适配内容;返回已访问组合、图片尺寸测量、布局拖动或资源 extent 变化只归一化并保留该组合的当前 viewport,不得意外重置用户已经完成的平移和缩放。普通平移不夹取 x/y;缩放仍受共享画布的最小/最大比例限制。初次 fit 与显式复位只使用资源卡真实包围盒,不把导航最小尺寸、原点空区或额外布局 gap 算入,并以 `16px` 紧凑留白在共享缩放上限内尽量铺满视口。
- 资源卡拖动使用 `5px` 阈值区分点击与移动;移动期间按当前 scale 乐观换算世界坐标、显示拖动态并同步依赖线,释放时提交一次 `manuallyPlaced=true` 布局 CAS,取消则回滚预览且不提交。拖动后的释放点击不打开详情。
- 依赖模式只在当前栏目画布内显示两端都属于该栏目的合法精确引用;装饰 SVG 与视觉隐藏的关系说明消费同一组可见边,搜索隐藏任一端点时两者同步移除。任务流仍只参与同类型布局聚类,不绘线也不进入关系说明。
- 依赖模式只在当前栏目画布内显示两端都属于该栏目的合法精确引用;装饰 SVG 与视觉隐藏的关系说明消费同一组可见边,搜索隐藏任一端点时两者同步移除。依赖线的 viewport 测量按动画帧合并,平移和缩放只更新已挂载观察器消费的最新 viewport,不得在每次输入时重建 ResizeObserver、scroll 或 resize 监听。任务流仍只参与同类型布局聚类,不绘线也不进入关系说明。
- 资源详情卡包含元数据、媒体预览和“编辑资源”操作,但不使用全屏 backdrop、不声明 `aria-modal=true`、不把 `focusedResource` 作为背景工具栏渲染条件。角色资源同时显示“生成动画”时,两个业务操作按钮必须使用一致样式,不能依赖 DOM 中的首按钮位置。桌面端允许继续操作背景画板;窄屏可以使用有边界的贴边卡,但背景组件必须保持挂载。
- 完全空项目继续使用可纵向滚动的五分区展览,不挂载分页画布或依赖画布的 `overflow: hidden` 交互壳;低高度窗口在两种排序模式下都能滚动到“项目版本”。
- 在“按依赖 / 按类型”之间切换或离开资源管理进入运行视图后返回时,恢复对应“排序模式 + 栏目”的现有 viewport,不自动触发“复位资源画布”,也不得用另一排序模式的 viewport 覆盖用户已经完成的平移和缩放。首次 fit 与用户显式复位仍使用同一套真实资源包围盒算法。