导出面板的用例去掉恒真的存在性断言

- getBy* / findBy* 找不到元素就抛,外面那层 expect(...).not.toBeNull() 永远不会失败:删掉它,等待出现改用 findBy*,需要对照的用 queryBy* + toBeNull()
- 能写成行为的就别写成存在:有脚本时点按钮行的「适配」看 adapt 是否被调用;读失败时同样点一下证明入口没变成摆设;切 tab 后补一条「卡片没有重新长回来」的负向断言
- artifactsPanel 三个目标改用 role=button(可点入口,不是三行说明文字),保留 querySelector 那几条(它们真的会返回 null)
- team-conventions 记下这条断言口径,并给「不建立固定频率轮询」补上导出面板对 .export/ 的显式例外(那两件事实没有事件源,只能现读)
This commit is contained in:
2026-10-05 19:51:52 +08:00
parent 832fca8ae1
commit f5a3ef8241
4 changed files with 34 additions and 23 deletions
@@ -58,6 +58,7 @@
- `5e2426c8a` 导出收尾判据抽成 `conclude(...)` 并补 5 例确定性用例(非零退出 / 超时 / 产物缺失 / 空产物 / 成功),同时去掉 `XHSMiniToolExportRunResult.exitCode` 这个恒为 0 的死字段;`463341c4b` 导出成功后把脚本输出尾部报给用户;`b3be3ee71` 证据口径修正;`5dd158ee1` 补默认 ignore 的真实起进程用例。
- `1b7741ac6` 适配与修复指令补上「包根在 game/ 时落点写成 `../.export/xhs-minitool.zip`」,skill 契约同步(manifest `2026-08-26.42`);`f8ed4e898` 保存对话框的默认文件名收进下载助手并复用既有取文件名工具;`90f651ddf` 刷新时先撤掉待触发的自动保存(附回归用例;该行为已被下面的自动刷新取代——轮询不再撤掉待保存的输入,因为「磁盘为准」的刷新动作没有了)。
- `ac666daad` 之后:未适配提示改成带入队按钮的卡片、失败卡片按变体分派适配/修/重试、提示只在注册表读回来之后出现(同一时刻只有一张卡片、一个入口)。
- 导出面板的用例去掉恒真的存在性断言(`getBy*` 本来就抛,不再包 `expect(...).not.toBeNull()`;等待出现改用 `findBy*`,能写成行为断言的就点一下按钮看回调),并把这条口径写进 team-conventions。
- layout 的用例重写:原来那条 `assert_eq!(artifact_relative_path(), format!(...))` 只是把实现抄了一遍,现改成 4 条只钉关系的用例(相对路径与宿主 `PathBuf` 指向同一文件、不许跑出 `.export/` 且不出现反斜杠、注册表与产物共用一个项目根锚定的 flat 目录、脚本名保住 `build:<后缀>` 形式);逐条反证过会红,`export::` 50 → 53 例。
- `dffe4de55` 导出链路按 ADR 收口(策略拒绝与宿主故障拆成两个变体、输出尾部只回原文与省略量);`df3a6826b` 前端失败通道按 ADR 分流(宿主故障与未分类拒绝原样抛出并去重)与复制失败可见反馈。
- 复制按钮改用 Tauri 剪贴板插件(原 `navigator.clipboard` 在 WebView 里可能根本没有,失败还会静默吞掉),失败态在按钮上可见。
@@ -43,6 +43,7 @@
- AGC 模板库灰度复用 `agc:template-library`:未配置关闭,已配置时遵循现有灰度启停、用户 ID/标签和比例规则;服务端返回权威结论,客户端入口和原生清单/下载/建项均执行门禁,主体切换丢弃旧异步结果。公开 OSS 不是保密边界,已创建项目不受影响。
- 画布卡片类型与信息角标共用 `CanvasCardCornerActions`;菜单收纳共用 `OverflowActions`,宿主决定展示数量和资源命令。AGC 选中菜单前 5 项直显,Web 默认不折叠;浮层 portal 继续接入现有画布关闭与滚轮归属判据。
- 断言只写在能失败的地方:`getBy*` / `findBy*` 找不到就抛,不要再包一层 `expect(...).not.toBeNull()` / `toBeDefined()`(那种写法恒真,还让每条查询多一层噪声);等元素出现用 `findBy*` 或 `await waitFor(() => screen.getBy*())`,负向用 `queryBy*` + `toBeNull()`。同理不写复述实现的断言(例如把被测函数的表达式在测试里再抄一遍),改为钉关系、边界或行为,并能逐条反证会红。
- 修改范围保持聚焦;优先扩展现有系统、页面、组件、DTO 和脚本。
- Agent 可见内容直接描述当前任务、输入和成功条件,细节按调用需要提供。
- AGC 外置智能体提示词只写模型必须遵守的指令与契约(工具名与参数、调用顺序、禁止项、失败处理、产物要求),不写客户端/宿主怎么实现:内部预算字段与限额、内部状态机与枚举、执行器锁与沙箱技术栈、进程/插件部署、注入与投影管线都属于宿主实现,一律改写成对应行为要求或删除。
@@ -52,7 +53,7 @@
- 后端遵循 `module-*`、`spacetime-module`、`spacetime-client`、`api-server`、`platform-*`、`shared-contracts` 的现役边界。
- 前端只负责表现、交互和临时 UI 状态;正式状态来自后端投影、API 或持久化契约。
- AGC 渲染层是离线前端:平台接口、OSS 素材直传、Provider、错误上报与账户/认证的网络 IO 全部在 Rust 的 reqwest facade,渲染层不得再出现 `fetch(` / `XMLHttpRequest` / `EventSource` / `sendBeacon(` / `new WebSocket(` 或 `@tauri-apps/plugin-http`;客户端窗口 capability 也不得授予 `http:default`。`check:native-shells --groups=contract` 的 `ai-game-creator-shell-user-dev-boundary` 用负向门禁钉住这条,改动渲染层网络边界必须同批改该门禁与 `build-release.test.mjs`。
- AGC 工作区的正式状态变化走 Rust 事件 + 一次受控快照读取,不建立固定频率轮询(纯 UI 计时器、拖拽重复器与动画 tick 除外):渲染层先订阅再读快照,事件重复或内容未变时保持数组身份,卸载后迟到事件不写回。Direct 活动回合的唯一事实源是 Direct 线程管理器的活动回合快照(`list_direct_active_turns` 只读它;登记、进度内容变化与收口各广播一次 `game-creator-direct-active-turns-changed`),渲染层与 Rust 都不得再引第二份注册表。
- AGC 工作区的正式状态变化走 Rust 事件 + 一次受控快照读取,不建立固定频率轮询(纯 UI 计时器、拖拽重复器与动画 tick 除外;导出面板对 `.export/` 注册表与 npm 脚本的 2 秒重读是显式例外——那两件事实由用户项目和 agent 直接改文件,没有事件源,只能现读):渲染层先订阅再读快照,事件重复或内容未变时保持数组身份,卸载后迟到事件不写回。Direct 活动回合的唯一事实源是 Direct 线程管理器的活动回合快照(`list_direct_active_turns` 只读它;登记、进度内容变化与收口各广播一次 `game-creator-direct-active-turns-changed`),渲染层与 Rust 都不得再引第二份注册表。
- AGC 维护态(平台 `503` 且命中 `MAINTENANCE` 或「维护」)由 Rust 在平台请求的错误分支经 `platform_maintenance::watch_platform_response` 分类并广播 `genarrative-client-maintenance-detected`;渲染层只订阅并打开唯一的「系统维护中」弹窗,不自行解析 HTTP,业务面板各自的错误文案保持不变。
- 对已明确退役且无现役调用方、公开契约、持久化数据、活跃实例或迁移要求的对象,直接清理实现、专属测试和说明,将权威文档更新为当前状态;历史由 Git 保存。公开契约、持久化数据和正式迁移按实际需求保留最小兼容及对应测试。
- 修改 `/api/external/v1` 时,同批更新 `docs/openapi/genarrative-external-v1.openapi.json` 与契约测试。