Related: #99
Baseline implementation: #100
背景
PR #100 已把移动端 L4 收敛为可复核的验收事务:clean standalone Release、fresh owned device、唯一 iOS Maestro/XCUITest lifecycle、Photos Picker 语义 readiness、导出断言、设备清理,以及不覆盖 primary failure 的有界证据。其最终 exact-head full run 双端 10/10 通过。
但这不等于标准 GitHub-hosted macOS 上的首样本已经稳定。#99 的 15 次 exact-head fresh iOS targeted 样本为 9/15 通过;失败漂移到 app-service、SpringBoard、addmedia 与 Picker selection-return 边界。高宿主压力的成功、失败样本互相重叠,尚无单一资源阈值或可证伪的恢复动作。
本 Issue 不回退 #100 的真实性与证据契约,而是在其基线之上评估怎样提高首样本稳定率,让 full E2E 既能发现产品回归,也不会被 hosted infrastructure 噪声长期淹没。
开源 RN 项目的公开策略
公开 workflow 显示,主流项目同样面对 Simulator、driver 与宿主长尾;它们通常通过改变执行面和门禁范围治理,而不是证明标准 hosted runner 天然稳定:
- React Native:iOS E2E 使用
macos-15-large,预构建 artifact 后测试;外层 E2E 最多三轮,单 iOS flow 还有内部重试;另有 Maestro Cloud lane。参考 Test All 与 iOS E2E。官方 run 29572874439 在三轮 iOS E2E 后仍失败,说明长尾并非本项目独有。
- Expo:按受影响路径选择平台;iOS/Android 均将 build 与 device E2E 分 Job,以 immutable artifact 连接;清理 Simulator runtime,并对 boot/失败 flow 做有界恢复。参考 Test Suite。
- Mattermost Mobile:iOS build 与 test 解耦,默认按时长拆成多 shard;workflow 明确记录
macos-26 的 Metro/Detox timing issues,并曾回退 macos-15。参考 iOS E2E template。
- Rocket.Chat RN:iOS/Android 各构建一次再把 artifact 分给 shard;对 wedged CoreSimulator 单独分类,并只重跑失败 flow。参考 iOS workflow 与 runner script。
- Bluesky、Rainbow:完整 iOS E2E 使用
macos-26-xlarge,并放在 nightly、手动或带标签的 PR 上;不是每个普通 PR 都在标准 runner 上跑双端 full。参考 Bluesky nightly 与 Rainbow iOS E2E。
这些项目的最终绿色 check 可能包含更强 runner、路径裁剪、分片、缓存、云设备或重试,不能与 PlogKit 当前的“exact SHA、双端 full、fresh device、禁止隐藏 retry、导出与 cleanup 均验收”直接比较。
当前 PlogKit 策略
- 普通 PR CI:静态、单元、render、iOS compile、Android compile。
- 手动 full L4:同一 SHA 双端并行;每个平台在各自 Job 内 clean build 后立即在同一宿主运行 fresh-device acceptance。
- iOS:标准
macos-26(3 M1 cores、7 GB RAM);系统门禁 → install/seed → 单一 Maestro suite → export assertions → owned-device cleanup。
- Android:标准 Linux + KVM emulator,独立于 iOS。
- 不使用固定 sleep、坐标、隐藏 retry、设备重建或全局 timeout 放宽;成功与失败均保留阶段化证据。
建议方案
第一阶段:同 SHA 对照 build/test 宿主隔离
保持 #100 为控制组,新增实验组:
控制组 A:同一 macOS Job clean build → fresh Simulator E2E
实验组 B:macOS build Job → exact-SHA immutable .app artifact
→ 全新 macOS Job → fresh Simulator E2E
Job B 的价值不是“构建进程退出后等 CPU 下降”,而是销毁构建 VM,一次性移除其 swap、缓存、后台服务、磁盘活动与会话状态。该设计也能让多个测试样本严格复用同一二进制。但它只是待验证假设:如果 CoreSimulator 在全新标准 runner 上仍有同类长尾,就不应因架构看起来先进而采纳。
约束:
- artifact 必须绑定 commit SHA、Xcode/Expo/RN 输入与 Release 配置,并做内容校验;不允许跨不可信 PR 复用可写 cache。
- 两组不得 retry、重建设备或扩大现有 timeout;失败样本全部计入。
- 每组至少 10 次 fresh iOS 样本;条件允许时使用 20 次,且交错执行以减少时间窗口偏差。
- 记录首样本成功率、失败阶段、阶段 p50/p95/max、总耗时、Actions 分钟与 artifact 开销。
- 只有实验组相对控制组出现具有实际意义且可重复的改善,才修订 ADR 0042 并迁移正式 workflow。
第二阶段:依据第一阶段证据选择
- 若新宿主显著改善:采用 build artifact → fresh test host;再评估是否以同一 artifact 做有界 shard,优先缩短单宿主 device 生命周期。
- 若改善不明显:保持现状,不引入 artifact orchestration;仓库未来迁入有资格的 Team/Enterprise 组织后,再做 standard 与 larger runner 的同 SHA A/B。GitHub larger runners 当前仅面向符合条件的组织/企业,不为个人仓库创建不可运行配置。参考 GitHub larger runners。
- 若仍无法达到可接受首样本稳定率:评估 dedicated/self-hosted Mac 或 Maestro/EAS device cloud;必须单独记录成本、安全、签名、网络和测试语义变化,不能悄悄把 simulator acceptance 替换为不同测试面。
非目标
- 不通过 retry 把首轮基础设施失败折叠成绿色。
- 不继续堆叠 readiness probe、固定 sleep、自动 reboot/rebuild 或更宽 timeout。
- 不把
load、free memory 或 swap 的单一数字当作跳过测试的阈值。
- 不因其他项目的绿色 badge 降低 PlogKit 的 export、cleanup 或 exact-SHA 验收语义。
- 不在本 Issue 中把调查数据复制进长期 ADR;只有正式改变架构时才修订负责该决策的 ADR。
验收条件
Related: #99
Baseline implementation: #100
背景
PR #100 已把移动端 L4 收敛为可复核的验收事务:clean standalone Release、fresh owned device、唯一 iOS Maestro/XCUITest lifecycle、Photos Picker 语义 readiness、导出断言、设备清理,以及不覆盖 primary failure 的有界证据。其最终 exact-head full run 双端 10/10 通过。
但这不等于标准 GitHub-hosted macOS 上的首样本已经稳定。#99 的 15 次 exact-head fresh iOS targeted 样本为 9/15 通过;失败漂移到 app-service、SpringBoard、
addmedia与 Picker selection-return 边界。高宿主压力的成功、失败样本互相重叠,尚无单一资源阈值或可证伪的恢复动作。本 Issue 不回退 #100 的真实性与证据契约,而是在其基线之上评估怎样提高首样本稳定率,让 full E2E 既能发现产品回归,也不会被 hosted infrastructure 噪声长期淹没。
开源 RN 项目的公开策略
公开 workflow 显示,主流项目同样面对 Simulator、driver 与宿主长尾;它们通常通过改变执行面和门禁范围治理,而不是证明标准 hosted runner 天然稳定:
macos-15-large,预构建 artifact 后测试;外层 E2E 最多三轮,单 iOS flow 还有内部重试;另有 Maestro Cloud lane。参考 Test All 与 iOS E2E。官方 run 29572874439 在三轮 iOS E2E 后仍失败,说明长尾并非本项目独有。macos-26的 Metro/Detox timing issues,并曾回退macos-15。参考 iOS E2E template。macos-26-xlarge,并放在 nightly、手动或带标签的 PR 上;不是每个普通 PR 都在标准 runner 上跑双端 full。参考 Bluesky nightly 与 Rainbow iOS E2E。这些项目的最终绿色 check 可能包含更强 runner、路径裁剪、分片、缓存、云设备或重试,不能与 PlogKit 当前的“exact SHA、双端 full、fresh device、禁止隐藏 retry、导出与 cleanup 均验收”直接比较。
当前 PlogKit 策略
macos-26(3 M1 cores、7 GB RAM);系统门禁 → install/seed → 单一 Maestro suite → export assertions → owned-device cleanup。建议方案
第一阶段:同 SHA 对照 build/test 宿主隔离
保持 #100 为控制组,新增实验组:
Job B 的价值不是“构建进程退出后等 CPU 下降”,而是销毁构建 VM,一次性移除其 swap、缓存、后台服务、磁盘活动与会话状态。该设计也能让多个测试样本严格复用同一二进制。但它只是待验证假设:如果 CoreSimulator 在全新标准 runner 上仍有同类长尾,就不应因架构看起来先进而采纳。
约束:
第二阶段:依据第一阶段证据选择
非目标
load、free memory 或 swap 的单一数字当作跳过测试的阈值。验收条件
pnpm verify、普通 PR CI、exact-head Android full 与 iOS full 均通过。