发布独立游戏聊天0.1.1并强化试玩验收
新增只能打开游戏聊天页的0.1.1独立release构建配置。 内置Runner启动、诊断日志、Windows后台进程与退出收束。 修复自动预览启动、同页版本刷新和结构化验收状态展示。 强化试玩协议、窗口末端采样与固定失败识别,允许正常输赢但拒绝无法推进。 完善旧验收回执自愈和当前场景指纹完成门。 补齐Rust、前端、真实Chrome回归测试及项目文档。
This commit is contained in:
@@ -26,6 +26,60 @@
|
||||
- 验证方式:序列化与字段上限测试、缺文件 / 损坏 / 原子恢复 / 链接安全测试、同 revision 双写最多一个成功、两种 mode 跨重启独立恢复、新增资源不移动旧坐标、`1280×800` 横屏无页面级溢出,以及 `npm run agc:typecheck`、定向测试、`npm run check:encoding`、`git diff --check`。
|
||||
- 关联文档:`docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`、`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`。
|
||||
|
||||
## 2026-07-31 generic-v1 使用稳定观察与当前场景指纹关闭试玩假阳性
|
||||
|
||||
- 背景:`game01` 的 start handler 会先同步发布 `playing`,再因碰撞错误在首个动画帧进入 `lost`;旧 `generic-v1` 只捕获 start / restart 后的瞬时 phase,同一 revision 因采样时机不同既能通过也能失败。与此同时,game-chat 把 `image.inspect` 工具调用的 `status=ok` 显示成绿色“截图已检查”,让工具执行成功进一步被误读为视觉验收通过。
|
||||
- 决策:`generic-v1` 初始状态固定要求 `ready` 且 `level > 0`。start 后必须进入 `playing`,并先持续观察 2 秒、取得至少 8 个实际样本,期间保持 `playing`,以确认玩家获得正常操作机会;再点击唯一可见、启用且真实可交互的 `data-playtest-id="primary-action"`。该控件必须执行真实主要玩法操作,并以 sequence 相对点击前严格推进证明操作已被接受。操作被接受前进入 `won | lost` 代表玩家没有获得正常操作机会,必须失败;操作被接受后的单次 `lost` 是合法结局,但不能成为所有受控尝试的唯一结果;若主要操作后仍为 `playing`,则继续观察 3 秒并取得至少 12 个实际样本,`won` 可提前证明非失败推进。随后 restart 必须推进 sequence、恢复到 `ready | playing`,并持续观察 3 秒、取得至少 12 个实际样本。若首轮结果为 `lost`,重开稳定后必须再执行一次必要的 start、2 秒 / 8 样本操作机会和真实 primary-action;第二次必须进入或保持 `playing`(再观察 3 秒 / 12 样本且不得转为 `lost`)或进入 `won`,两次受控尝试都固定 `lost` 代表无法正常推进的恶性 bug,必须失败。观察期间 sequence 不得回退,restart 窗口只能保持 `ready | playing`;样本数门槛与持续时长必须同时满足,窗口末端必须强制再读取一次有效状态。selector、观察时长、样本门槛、终态边界、非失败推进、末端覆盖、sequence 规则和 required assertions 全部纳入 scenario fingerprint。合同升级导致旧 fingerprint 不匹配时,回执读取与 plan liveness 把它视为 stale missing,允许同一 run 重新 `preview.validate` 自愈;身份、路径、digest 或内容完整性篡改仍失败关闭,最终完成门仍现场重算 fingerprint 并严格拒绝旧证据。game-chat 只有在结构化 `preview.validate` 同时给出 `passed=true` 与 `playtestPassed=true` 时才显示试玩通过并产生可玩 revision;`image.inspect status=ok` 只表示工具成功,`passed=null` 必须保持中性展示。
|
||||
- 影响范围:`generic-v1` 浏览器试玩执行器、scenario fingerprint、自主完成回执与持久浏览器报告校验、game-chat 进度证据和自动预览门禁;不改变 `lane-defense-v1` 合同或通用工具执行状态语义。
|
||||
- 验证方式:默认 Rust 回归锁定初始状态、真实 `primary-action`、操作机会前后终态边界、2 秒 / 8 样本 start 操作机会、操作后仍为 `playing` 时的 3 秒 / 12 样本、restart 的 3 秒 / 12 样本、首轮 `lost` 后的第二次非失败推进、强制窗口末端采样、sequence 规则、stale 自愈与当前 fingerprint;显式运行 `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml real_chrome_generic_playtest_ --features game-chat-release -- --ignored --nocapture --test-threads=1`,同时确认真实 Chrome 中未接受主要操作就瞬时 `lost`、两次受控尝试都固定 `lost` 均判失败,首轮合法 `lost` 后重开并证明非失败推进判通过;前端定向测试确认缺少双 true 的 preview 证据不显示通过,`image.inspect passed=null` 使用中性色。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-30 game-chat 0.1.1 的用户预览由 Tauri 持有并按验证 revision 原位刷新
|
||||
|
||||
- 背景:External Runner 和 Tauri 客户端各自拥有进程内 `PreviewRegistry`。Runner 完成 `preview.validate` 后,其 server 与 running 状态不会出现在 Tauri registry,导致已有可玩版本时用户预览不自动出现;后续 revision 即使验证成功,既有 iframe 也可能继续显示 WebView 缓存中的旧资源。顶部只写“未启动”还会让用户无法判断是 Runner、Runtime 还是预览未启动。
|
||||
- 决策:game-chat 用户可见 preview 只由 Tauri 客户端启动、持有和停止,不共享或复用 Runner registry 的 server。客户端只接受当前 accepted Supervisor 父 run 下真实 `preview-playtest` scheduler child 的结构化 `preview.validate` 证据;同 revision 以最新事件为准,时间相同时失败优先,且证据 revision 必须精确等于项目当前原子 sidecar revision。首次满足门禁后,Tauri 自动启动一次 preview server 并显示 iframe;启动命令携带 `expectedRevision`,后端取得项目写锁后再次原子比对,避免检查与启动之间的 revision 漂移。same-run steer 的一次性授权使用 v2 持久 cursor 与唯一 generation ID,旧验证或旧异步 attempt 不能消费新授权;旧 attempt 的补偿清理按完整 preview identity 原子停止 registry server,资源停止不得被项目 `preview.stop` policy 或项目锁等待阻断,后续状态持久化不能覆盖同项目新 server 的 running 状态。同一 run 后续成功验证的更高 revision 只刷新原 iframe,不重复 `preview.start` 或新增 server,相同或更低 revision 不刷新。preview HTTP 响应统一使用 `Cache-Control: no-store`,确保刷新读取当前 revision;无用户可见预览时顶部明确显示“预览未启动”。本次专用 release 版本推进为 `0.1.1`。
|
||||
- 影响范围:game-chat 自动预览授权、Tauri / Runner `PreviewRegistry` 进程边界、用户可见 preview server 生命周期、iframe revision 刷新、preview HTTP 缓存策略、顶部状态文案和专用 release 版本;普通客户端入口、Runner 验证语义和平台后端不变。
|
||||
- 验证方式:以当前 run 成功 `preview.validate` revision N 后断言 iframe 自动出现且 server 归 Tauri registry;再完成 revision N+1,断言 server 进程和 loopback origin 不变、iframe 重新加载新内容且所有响应为 `no-store`。Runner registry 单独 running 不得让页面显示预览;相同 / 更低 revision 不得刷新;停止预览后顶部必须显示“预览未启动”;构建产物和安装信息必须为 `0.1.1`。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-30 Provider 503 等待与耗尽状态使用严格字段派生的安全摘要
|
||||
|
||||
- 背景:game-chat 的进度卡只显示“等待 Provider upstream-5xx 瞬态故障退避到期”,没有 HTTP 状态、重试次数或等待时间;重试耗尽后,Runtime 和持久 conversation 又可能直接展示 `fingerprint/chars` 或 `<absolute-path> [redacted sensitive context]`,用户既无法判断是否在恢复,也看不到可操作的失败原因。
|
||||
- 决策:重试资格继续按稳定错误类别判断,durable retry record 额外保留精确且不含正文的 `upstream-<status>`;等待态从 record 派生 HTTP 状态、真实 attempt 上限和退避剩余秒数。耗尽态只在 `kind/httpStatus/fingerprint/chars/retryAttempt/maxRetries/retryState` 全部严格匹配时派生安全中文摘要;Runtime 私有机器字段可供确定性投影,但状态卡和持久 conversation 不显示 fingerprint、字符数、绝对路径、脱敏占位符或 Provider 正文。所有写入“后台任务失败”conversation 的生产分支统一经过同一安全 formatter,其它错误只显示固定失败文案。
|
||||
- 验证方式:Rust mock 503 覆盖等待、恢复与耗尽,断言 exact HTTP status、attempt、sidecar 清理和正文零泄漏;前端模型覆盖状态卡优先级、严格字段解析、字段不一致与尾随正文失败关闭;conversation 测试覆盖 Provider URL/query、API Key、绝对路径、fingerprint、chars 和 redaction marker 均不可见。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-30 game-chat 独立版退出时收束 Runner 整棵 Windows 进程树
|
||||
|
||||
- 背景:独立包原先在 Tauri 最终退出时仅调用一次 `runner.shutdown_if_idle`;若 Runner 正忙便返回 busy 且没有稍后关闭闩锁,Runner 和后台命令会永久残留。`command.exec / project.verify` 只有进程组 flag,STDIO MCP、Git 和清理命令也缺少 `CREATE_NO_WINDOW`,因此 Windows release 会连续弹出多个控制台窗口。
|
||||
- 决策:仅 game-chat release 新增认证 `runner.shutdown_for_client_exit`:立即进入 draining、拒绝新写并请求结束当前 boot,不删除 durable sidecar、不伪造任务 completed,重启后继续走 reconciliation。Windows 客户端以 `CREATE_SUSPENDED` 创建自己启动的 Runner,在其执行前加入由客户端持有的 kill-on-close Job,复核并恢复唯一主线程;Job 分配或恢复失败必须 kill + wait 并令启动失败,使客户端崩溃、IPC 关闭失败或 Runner 异常退出时整棵未 breakaway 后代仍能收束。普通 dev / release 与 CLI 保持 `shutdown_if_idle`。所有非交互后台命令统一使用 `CREATE_NO_WINDOW`,需要独立终止边界时叠加 `CREATE_NEW_PROCESS_GROUP`,不使用 `DETACHED_PROCESS`;独立 flavor 同时拒绝再打开 launcher / workspace 平行窗口。
|
||||
- 验证方式:定向测试覆盖专用 RPC 的 draining / shutdown 与普通 idle 语义不变;正式安装包在活跃任务期间确认无后台控制台窗口,关闭主窗口后核对 Runner、MCP、command、ConPTY 和孙进程全部退出,再启动确认 durable 状态正确 reconciliation。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-30 Windows Runner 新建私有控制文件在原子安装前初始化 TokenUser owner
|
||||
|
||||
- 背景:Windows 即使已把 game-chat AppData 目录 owner 设为当前 `TokenUser`,本进程新建 `agent-runner.lock`、endpoint 临时文件、项目 execution-owner 诊断临时文件和 real-E2E 私有文件的 owner 仍可能来自 token 默认 owner `Administrators`。Runner 会依次在 lock 或 endpoint 的严格 `TokenUser` 复核处退出;父进程此前还会在已经观察到子进程退出后继续等待完整 30 秒。
|
||||
- 决策:既有 durable 文件的读取继续严格拒绝 foreign owner。只有本进程以 `create_new` 创建且仍持有 Windows `share_mode(0)` 独占句柄、并通过普通文件 / 非 reparse / 单链接检查的临时文件,才在写入和原子安装前初始化 `TokenUser` owner 与 protected 私有 DACL,失败时关闭句柄并清理刚创建的文件;安装后继续严格复核。固定 `agent-runner.lock` 的 stale 恢复还要求父目录是已验证的私有 AppData;活锁不可接管或截断,只有 sharing / lock violation `32/33` 表示占用。父进程观察到 Runner 子进程退出后立即返回真实错误,不再空等启动 deadline。Tauri `.setup()` 内的致命失败在记录日志后直接显示诊断路径。
|
||||
- 影响范围:Windows External Runner 单实例锁、endpoint、项目 execution-owner 诊断、real-E2E 私有 checkpoint、启动失败耗时和 game-chat release 错误可见性;既有配置 / endpoint / 项目 durable 文件的读取边界、普通 dev / release 与 Runner 活跃任务语义不放宽。
|
||||
- 验证方式:Windows 定向测试覆盖 endpoint 原子写入与 TokenUser 复核、new/stale lock owner 修复、活锁不截断、hardlink / reparse 不触碰目标、project-owner 诊断 TokenUser 复核、错误码精确分类,以及子进程退出在 2 秒内返回;正式包在现场 TokenOwner 为 Administrators 的机器上必须依次出现 `startup.runner.start.complete`,创建项目任务时 execution-owner 诊断也必须成功。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-29 game-chat 使用独立 release flavor
|
||||
|
||||
- 背景:game-chat 已完成开发态页面和自主 Runtime 链路验证,需要交付一个无参数启动、只能进入该页面的 release 包,同时不能改变普通客户端入口、安装身份、AppData 或 Runner 的持久任务语义。
|
||||
- 决策:新增 `npm run agc:build:game-chat-release`,通过 Rust `game-chat-release` feature 和编译期前端入口锁定生成独立 NSIS 包。该 flavor 的 `productName` 为 `Genarrative Game Chat`,`identifier` 为 `world.genarrative.ai-game-creator.game-chat`,使用独立安装身份与 AppData;前端直接渲染本地 `GameChatReleaseApp`,不经过平台 `AuthenticatedClient`,本地工作台不依赖 `api-server`。普通 dev / release 与 debug game-chat 保持原认证入口和配置。独立客户端退出语义已由 2026-07-30 专项决策收口为 `runner.shutdown_for_client_exit + Windows kill-on-close Job`,不再沿用活跃 Runner 返回 busy 后继续驻留的旧规则。
|
||||
- 影响范围:AI 游戏创作壳的构建脚本、Tauri 配置、Rust feature、前端入口选择、独立 AppData 和 game-chat release 退出处理;普通 AI 游戏创作 dev / release、debug 认证、Supervisor Runtime 协议和后端接口不变。
|
||||
- 验证方式:执行壳配置门禁、AppSurface game-chat 测试、前端类型检查、相关 Rust 定向测试、`npm run check:encoding` 与 `git diff --check`;运行 `npm run agc:build:game-chat-release` 后 smoke 无参数首屏、断开 `api-server` 的本地工作台、页面隔离、独立 identifier / AppData、普通/debug 认证不回归,以及空闲 / 活跃两种 Runner 退出分支。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-29 Windows 客户端 AppData 以 TokenUser 安全迁移并为 game-chat 提供有界诊断
|
||||
|
||||
- 背景:Windows 安装包首次创建 AppData 时若沿用继承 owner,目录 owner 可能是 Administrators 而非当前登录用户;后续严格 owner 校验会让客户端在 `.setup()` 阶段退出,且无控制台 release 缺少可见诊断。直接修改 foreign-owner 旧目录的 ACL 还可能覆盖其它主体持有的数据或跟随 reparse 路径。
|
||||
- 决策:新建客户端 AppData 时以进程 `TokenUser` SID 显式设置 owner 和当前用户私有 DACL,不使用 `TokenOwner` 代表用户。历史 foreign-owner 真实目录先原子重命名为同级唯一 `.owner-mismatch-backup-*`,再重建并回读验证安全目录;任何 reparse / junction / symlink、备份冲突或迁移失败都失败关闭,不在旧目录上放宽权限。独立 release 的 `startup.log` 和记录 Runner stdout / stderr 摘要的 `agent-runner.log` 均采用 256 KiB 上限、仅一份 previous 和脱敏写入;AppData 日志不可写时 `startup.log` 回退系统 TEMP,Tauri URL、AppData、Runner、`.setup()` 或 `.build()` 初始化失败时在 Windows 显示包含诊断日志位置的错误对话框。
|
||||
- 影响范围:AI 游戏创作客户端 AppData 首次创建与历史目录迁移、Windows owner / DACL 校验,以及 game-chat release 的启动和 Runner 诊断、初始化失败体验;不改变项目目录、Runtime durable 数据合同或活跃 Runner 退出语义。
|
||||
- 验证方式:Windows 定向测试覆盖 TokenUser owner、私有 DACL、foreign-owner 同级备份不覆盖和 reparse 拒绝;诊断测试覆盖 256 KiB 单 previous 轮转、凭据与绝对路径脱敏、AppData 不可写时 TEMP 回退和初始化失败对话框。安装包 smoke 后保留旧备份证据并确认新 AppData 可写、Runner 可启动。
|
||||
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`。
|
||||
|
||||
## 2026-07-29 game-chat 在创建 WebView 前确定初始 URL
|
||||
|
||||
- 背景:`agc:game-chat` 曾在 Tauri `.setup()` 中读取仍可能是 `about:blank` 或配置期地址的 `client.url()`,再导航到 game-chat;Windows WebView2 首航被覆盖后只剩黑边白块或全白原生窗口,刷新无法恢复。
|
||||
|
||||
@@ -59,6 +59,34 @@ AI 游戏创作独立客户端常用短命令:
|
||||
npm run agc
|
||||
```
|
||||
|
||||
需要构建只能打开“游戏运行 + 聊天”页面的独立 release 包时使用:
|
||||
|
||||
```bash
|
||||
npm run agc:build:game-chat-release
|
||||
```
|
||||
|
||||
该命令启用 Rust `game-chat-release` feature,并配合编译期前端入口锁定生成独立 NSIS 包。当前专用 release 版本为 `0.1.1`;产物的 `productName` 为 `Genarrative Game Chat`,`identifier` 为 `world.genarrative.ai-game-creator.game-chat`,安装身份和 AppData 不与普通 AI 游戏创作客户端混用。独立包直接渲染本地 `GameChatReleaseApp`,绕过平台 `AuthenticatedClient`,进入本地项目工作台不依赖 `api-server`;普通 `npm run agc`、`npm run agc:dev`、debug game-chat 和 `npm run agc:build` 继续走既有认证入口与配置。
|
||||
|
||||
game-chat 的用户可见 preview 必须由 Tauri 客户端 `PreviewRegistry` 持有。External Runner 和 Tauri 的 registry、server 句柄与 running 状态是进程内资源,不得互相推断或把 Runner 验证用 server 直接交给 iframe。当前 accepted Supervisor 父 run 下真实 `preview-playtest` scheduler child 首次给出结构化成功证据、且其 revision 精确等于项目当前 revision 后,客户端才消费一次性授权并启动一个 Tauri preview server,随后自动显示 iframe;`preview.start` 必须携带 `expectedRevision`,Tauri 在取得项目写锁后再次原子比对。same-run steer 授权必须记录授权前 revision / validation cursor 和唯一 generation ID,旧证据、旧 policy await 或旧 start 返回均不能清除新授权。同一 run 的更高 validated revision 只刷新原 iframe,不能重复 `preview.start` 或新增 server,相同 / 更低 revision 不刷新;同 revision 的最新失败证据必须关闭该 revision 的可玩判定。preview HTTP 的 HTML、脚本、样式、资源和错误响应都必须返回 `Cache-Control: no-store`。没有 Tauri 用户预览时,顶部状态必须显示“预览未启动”,不能只写“未启动”。
|
||||
|
||||
`generic-v1` 的真实试玩必须从 `ready` 且正整数 level 开始;start 推进到 `playing` 后,必须先持续观察 2 秒并取得至少 8 个实际样本,期间保持 `playing`,以确认玩家获得正常操作机会;随后点击唯一可见、启用且真实可交互的 `data-playtest-id="primary-action"`,由该控件触发真实主要玩法操作,并以 sequence 相对点击前严格推进证明操作已被接受。操作被接受前进入 `won | lost` 代表玩家没有获得正常操作机会,必须失败;操作被接受后的单次 `lost` 是合法结局,但不能成为所有受控尝试的唯一结果。若主要操作后仍为 `playing`,则继续观察 3 秒并取得至少 12 个实际样本;`won` 可提前证明非失败推进。之后 restart 必须推进 sequence、恢复到 `ready | playing`,并持续观察 3 秒、取得至少 12 个实际样本;若首轮结果为 `lost`,重开稳定后必须再执行一次必要的 start、2 秒 / 8 样本操作机会和真实 primary-action,第二次必须进入或保持 `playing`(再观察 3 秒 / 12 样本且不得转为 `lost`)或进入 `won`。两次受控尝试都固定 `lost` 代表无法正常推进的恶性 bug,必须失败。各观察窗口内 sequence 不得回退,restart 窗口只能保持 `ready | playing`。样本数和观察时长必须同时满足,窗口末端必须强制再读取一次有效状态,不能靠前段样本数提前通过。selector、时长、样本门槛、终态边界、非失败推进、窗口末端覆盖、required assertions 和 sequence 规则都属于 scenario fingerprint。旧 fingerprint 回执在读取和 plan liveness 检查时按 stale missing 处理,让同一 run 可重新 `preview.validate`;身份、digest、路径或内容完整性篡改仍失败关闭,最终完成门仍须现场重算当前 fingerprint 并严格拒绝旧证据。
|
||||
|
||||
进度展示只把结构化 `preview.validate` 的 `passed=true && playtestPassed=true` 认作试玩通过,不从 `summary` 的 `:ok` 推断结论。`image.inspect status=ok` 只表示工具成功;`passed=null` 或缺少结构化布尔结论时显示中性“截图分析完成”,不得显示绿色通过。
|
||||
|
||||
真实 Chrome 回归必须用同一前缀同时覆盖尚未接受 `primary-action` 就瞬时进入 `lost` 的 FAIL、两次受控尝试都固定 `lost` 的 FAIL,以及首轮合法 `lost` 后重开并在第二轮证明非失败推进的 PASS:
|
||||
|
||||
```bash
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml real_chrome_generic_playtest_ --features game-chat-release -- --ignored --nocapture --test-threads=1
|
||||
```
|
||||
|
||||
修改 game-chat release flavor 后,至少执行壳配置门禁、AppSurface game-chat 定向测试、前端类型检查、AppData / 诊断日志 / release flavor 相关 Rust 定向测试、`npm run check:encoding` 和 `git diff --check`。打包 smoke 必须确认:安装信息和产物版本为 `0.1.1`;无参数启动直接进入且只能停留在 game-chat 页面;停止或断开 `api-server` 后本地工作台仍能打开;普通 dev / release 与 debug game-chat 仍走原认证入口;独立 AppData 生效。预览 smoke 应先让当前 run 成功验证 revision N,确认 Tauri registry 启动一个 server 且 iframe 自动出现;在 validate 后、start 取得锁前推进项目 revision,必须确认原子 `expectedRevision` 门禁拒绝启动且授权保留等待新证据;再验证 revision N+1,确认 server 进程和 loopback origin 不变、iframe 显示新版本且响应为 `no-store`。same-run steer 还要覆盖旧验证不消费新授权、旧异步 attempt 不清新 generation;Runner registry 单独 running、失败 / 相同 / 更低 revision 均不能触发用户预览或重复刷新,停止后顶部显示“预览未启动”。独立包退出时必须通过 `runner.shutdown_for_client_exit` 先进入 draining 再结束本 boot,保留 durable sidecar 供下次 reconciliation,不把中断任务写成 completed;Windows Runner 必须 `CREATE_SUSPENDED -> AssignProcessToJobObject -> ResumeThread`,分配或恢复失败时 kill + wait,客户端持有 kill-on-close Job 兜底,关闭主窗口后 Runner、MCP、command、ConPTY 及其后代都应消失。普通 dev / release 和 CLI 继续使用 `runner.shutdown_if_idle`。
|
||||
|
||||
Windows release 的非交互后台命令统一使用 `CREATE_NO_WINDOW`,包括 `command.exec / project.verify`、STDIO MCP、Repository Context Git、`git.inspect / project.git_commit` 和 `taskkill` 清理命令;需要进程组终止时再叠加 `CREATE_NEW_PROCESS_GROUP`,不要使用 `DETACHED_PROCESS`。smoke 时应在实际任务运行期间观察无额外控制台窗口,并在关闭客户端后核对整棵后台进程树为零,再重启确认 reconciliation 可继续。
|
||||
|
||||
Provider 失败回归必须同时检查等待态和耗尽态:用本地 mock 503 证明 Runtime 从 durable retry record 显示精确 HTTP 状态、真实 `nextAttempt/maxRetries` 和退避秒数;最后一次重试仍失败时,状态卡与持久 conversation 只显示安全中文摘要。测试正文应包含诱饵 Provider URL/query、API Key 和 Windows / Unix 绝对路径,并断言这些正文、内部 fingerprint / chars 与 `[redacted ...]` 占位符均未进入用户可见消息;不能只验证状态卡而漏掉 `SupervisorChatOnlyView` 直接渲染的 conversation。
|
||||
|
||||
Windows 安装包还必须覆盖 AppData 与诊断失败路径:新建目录的 owner 必须等于进程 `TokenUser` SID 且 DACL 仅允许当前用户;历史 foreign-owner 目录应先拒绝任何 reparse / junction / symlink,再原子重命名为同级唯一 `.owner-mismatch-backup-*` 并重建安全目录,旧配置不得覆盖。Windows 新建 Runner lock、endpoint temp、project-owner diagnostic temp 与 real-E2E 私有文件的 owner 可能仍是 token 默认 owner `Administrators`;只允许本进程 `create_new` 后仍持有不共享独占句柄、且句柄确认普通 / 非 reparse / 单链接的对象在写入或原子安装前初始化为 `TokenUser`,失败时清理该新文件。既有 durable 文件读取、活锁、access denied、硬链接或非固定 lock 路径不得删除、接管或截断。`startup.log` 与 `agent-runner.log` 达到 256 KiB 时只保留一份 `.previous.log`,并扫描 API Key、Authorization、AppData 和其它绝对路径零泄漏;AppData 不可写时 `startup.log` 应回退系统 TEMP 的 `Genarrative-Game-Chat-Diagnostics`,故意注入 `.setup()` / `.build()` 初始化失败时必须出现带诊断日志位置的 Windows 对话框;`.setup()` 发生在 `app.run` 阶段,错误对话框必须由 setup 失败路径直接触发,不能只处理 `.build()` 返回值。Runner 子进程已退出时父进程应立即报告,不得继续等待完整启动期限。
|
||||
|
||||
开发侧需要无 UI 验收某个单 Agent 的完整 Runtime 时使用:
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user