所有服务都必须来自本仓库的 tests/fixtures/workspace-server.ts,使用新建临时数据目录。以下端口只用于这些隔离实例;若被占用,先修改脚本端口,不要连接或停止现有服务。测试账号 fixture / fixture-pass 是夹具生成的合成账号。
从 yaoyao 开发 worktree 根目录执行:
node docs/verification/2026-09-13-bot-message-optimization/scripts/analyze.mjs
NODE_OPTIONS=--no-experimental-webstorage npm exec -- tsx tests/perf/workspace-message-latency.ts /tmp/workspace-message-performance.json
分析脚本默认读取归档 JSON;压力脚本自行创建并清理临时 SQLite 和 loopback SSE,校验完整回复、至少 60% SSE 降幅和 10 ms 写入/编码 P95。
/tmp/bot-latency-acceptance/{baseline-server,optimized-server,baseline-home,optimized-home,evidence}。git archive bed10cb 解包到 baseline-server,用开发分支最终提交解包到 optimized-server。两份副本不包含 .git。tests/fixtures/workspace-server.ts 复制到两份副本:只替换相同的确定性假上游,不替换各自产品服务端逻辑。它识别 [latency:唯一标记],包含 long 时输出 200 段,否则输出 40 片文字。scripts/instrument-web.py /tmp/bot-latency-acceptance,只给临时副本加时间探针;脚本拒绝修改 Git checkout。NODE_OPTIONS=--no-experimental-webstorage npm run build,等待两个构建成功后开始测试。在两个终端分别从相应副本启动:
WORKSPACE_FIXTURE_HOME=/tmp/bot-latency-acceptance/baseline-home WORKSPACE_FIXTURE_PORT=19351 WORKSPACE_FIXTURE_UPSTREAM_PORT=19352 ./node_modules/.bin/tsx tests/fixtures/workspace-server.ts
WORKSPACE_FIXTURE_HOME=/tmp/bot-latency-acceptance/optimized-home WORKSPACE_FIXTURE_PORT=19361 WORKSPACE_FIXTURE_UPSTREAM_PORT=19362 ./node_modules/.bin/tsx tests/fixtures/workspace-server.ts
确认日志显示临时 home 和相应端口后,从开发 worktree 启动代理,再运行 UI 验收:
node docs/verification/2026-09-13-bot-message-optimization/scripts/latency-proxy.mjs
node docs/verification/2026-09-13-bot-message-optimization/scripts/web-acceptance.mjs
代理监听 19371(基线)、19372(优化)、19359(夹具控制器),生成 connections.json 和网络记录。UI 脚本等待真实登录响应、使用独立浏览器上下文、唯一回复标记和完整文本断言,采集 DOM 更新时间;另外检查上翻后的快照恢复和新消息不改变阅读位置。运行期间不要并行构建或其他性能测试。
aceb477 和开发分支最终提交分别复制 YaoYaoAI、YaoYaoAITests、YaoYaoAIUITests、YaoYaoAI.xcodeproj、project.yml 到上述临时目录的 ios-baseline、ios-optimized。scripts/instrument-ios.py /tmp/bot-latency-acceptance。探针只添加到临时副本;完整消息内容只在测试完成时记录。YaoYaoAIUITests/LaunchSmokeTests/testLatencyCurrent。-configuration Debug -enableCodeCoverage NO SWIFT_OPTIMIZATION_LEVEL=-O CODE_SIGN_IDENTITY=- CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM=GMU6W5FKQ6。使用 ad-hoc 签名,以避免模拟器 Keychain 缺少 entitlement。simctl get_app_container 定位专用模拟器的 cn.samien.yaoyao.hermes,复制 Documents 中的 latency-*.jsonl;用 xcresulttool export attachments 导出实际截图。8ed6079 和开发分支分别构建 Debug APK;从开发分支构建 AndroidTest APK。WorkspaceLatencyTest 只依赖基线已有的公开界面;未提供 latency-url 时自动跳过。本机 SDK 为 /Users/samien/Library/Android/sdk,JDK 为 /Users/samien/.local/share/hermes-android-toolchain/jdk-17。模拟器启动需移除 http_proxy、https_proxy、all_proxy 及其大写变量,防止 QEMU 启动挂起;不要修改宿主系统代理。
adb -s emulator-5582 shell am instrument -w -r -e class cn.samien.yaoyao.hermes.WorkspaceLatencyTest -e latency-url http://10.0.2.2:19371 -e latency-product baseline-android cn.samien.yaoyao.hermes.test/androidx.test.runner.AndroidJUnitRunner
优化 APK 改用 19372 和 optimized-android。实际模拟器序列号可能不同,应替换为自己创建的设备。测试会校准时钟、核对完整文字、验证长回复末尾及用户上翻后的阅读位置。
用 adb pull 收集 /sdcard/Android/data/cn.samien.yaoyao.hermes/files/latency-evidence。把两端 JSON 放入 evidence 后运行分析脚本,并保留 OK (1 test) 日志与截图。
HERMES_YAOYAO_WORKSPACE_MESSAGE_PATCHES=0 重启,确认不再协商补丁,旧日志仍可通过 reset + snapshot 恢复。format=patch-v1;旧客户端直播仍收到完整消息。对应自动化用例在 workspaceMessagePatch.test.ts、workspaceSync.test.ts。