R8-Fix-7 E2 门禁修复(Test Contract Repair)
> 本档案是 R8-Fix-7 产品提交 a9f10968c71dc238825a8ff4427b2d04627a8ea2 > 的测试门禁修复快照。本批次不改动任何产品代码: > git diff <R8-Fix-7 提交>..HEAD -- MacApp/Sidecar/perfowl_collector_core 为空。 > 证据等级 E2;不构建 Build 69、不执行真机 E4、不声明 validated。
1. 问题
独立 clean-worktree 验收确认 R8-Fix-7 的产品实现方向正确: Realtime Consumer bounded burst 为 8 events / 1ms,bounded-burst 的真实 synthetic 结果 稳定优秀;Device Conditions 作用域与 Stop-aware 空闲等待行为正常;Swift 与站点门禁通过。
唯一的稳定阻断来自新 benchmark 对 legacy baseline 的错误断言, 另有一个既有的 1ms 极窄时间边界测试偶发抖动。两者都是测试契约缺陷, 不是产品缺陷。
基线提交上的独立复现:
focused Ran 197 tests FAILED (failures=2)
Python full Ran 703 tests in 92.341s FAILED (failures=3)
稳定失败 tests.test_realtime_consumer_fairness.DisplayPipelineBenchmark.test_benchmark_steady_120hz_7200_frames
偶发抖动 tests.test_display_pipeline_timing.PumpActiveBurstDurationTests.test_a1_active_duration_excludes_upstream_wait
2. 证据
2.1 legacy 在 120x 压缩 benchmark 下会真实撑爆有界队列
原 test_benchmark_steady_120hz_7200_frames 对 legacy 与 burst 两条路径同时要求 processed == 7200、sampleCount == 7200、droppedEventCount == 0、undrainedAtClose == 0, 并额外要求 legacy.handoffs == 7200。
legacy 是旧策略的行为模拟器(每条 Raw 一次 await asyncio.sleep(0)); Pmd3Subscription.__anext__ 在有界队列仍有 backlog 时同步返回。 测试把真实 60 秒的 120Hz 压缩 120 倍后,producer 的压力足以真实撑爆有界 pump 队列(2048)。 这是旧策略在高压下丢样的证据,不是环境偶发故障。
独立审计连续复跑的 legacy 侧数据:
| 复跑 | legacy processed | legacy drops | legacy P95 | burst processed | burst drops | burst P95 | burst Max |
|---|---|---|---|---|---|---|---|
| Run 1 | 5448 / 7200 | 1752 | 508.009ms | 7200 / 7200 | 0 | 5.317ms | 9.770ms |
| Run 2 | 5355 / 7200 | 1845 | 497.764ms | 7200 / 7200 | 0 | 5.509ms | 10.149ms |
| Run 3 | 5280 / 7200 | 1920 | 525.558ms | 7200 / 7200 | 0 | 5.657ms | 9.693ms |
| Python full | 5336 / 7200 | 1864 | 478.606ms | 7200 / 7200 | 0 | 5.517ms | 9.510ms |
本批次复现时进一步确认 legacy 的丢样数高度不稳定:一次 processed 6709 / drops 491 / p95 334.611ms,另一次 processed 7200 / drops 0 / p95 160.783ms。 一个在 0 与约 1900 之间大幅摆动的量不能被"零容忍"断言钉住。
2.2 1ms active-duration 测试把实现阈值当成机器测量上限
test_a1_active_duration_excludes_upstream_wait 原断言 active_ms < 1.0—— 而 1ms 正是 pump 的公平性预算本身。断言拿实现阈值当机器测量上限, 没有为两次 monotonic_ns 之间的调度抢占留余量。独立全量运行观测到 active_ms = 1.014 即判失败(单独重跑 5/5 PASS)。
3. 测试契约修正
3.1 benchmark 按语义拆开
| 测试 | 语义 | 断言 |
|---|---|---|
test_benchmark_shipping_policy_steady_120hz_7200_frames | R8-Fix-7 发布门禁,只对 bounded burst | processed/sampleCount == 7200、drops == 0、undrained == 0、handoffs == ceil(7200/8) == 900、p95 < 10ms、p99 < 10ms、max < 50ms、>500ms == 0 |
test_benchmark_legacy_vs_bounded_burst_under_pressure | legacy 对照,允许丢样 | legacy.processed > 0、legacy.sampleCount > 0、legacy.handoffs == legacy.processed、legacy.p50 > 10ms;burst 同形态零丢样;burst.p95 < legacy.p95 且 improvement > 30% |
test_benchmark_no_overflow_latency_comparator | 控制组:测试专用 8192 队列让两条路径都不丢样,隔离"调度策略"与"队列溢出" | 两条路径均 processed/sampleCount == 7200、drops == 0;burst.p95 / p99 / max < legacy 且 burst.handoffs < legacy.handoffs |
- legacy 的丢样数只打印、不 FAIL——历史行为模拟器不是 shipping implementation。
- 8192 只作为测试 fixture 参数传入;生产
Pmd3Subscription默认队列容量 2048 未改。 test_benchmark_backlog_reproduces_build68_and_improves_p95与
test_benchmark_backlog_tail_removes_the_over_500ms_queue_wait 保持不变、未削弱。
3.2 active duration 改为数量级分离
上游等待 5ms/事件 → 50ms/事件;断言改为 legacy_wall_ms > 40ms、active_ms < 10ms、 active_ms < legacy_wall_ms * 0.20、legacy_wall_ms - active_ms > 30ms。 若错误地把上游 await 计入,active_ms 将是 50ms 量级,四条断言必然全部失败—— 判别力只增强、不减弱。
4. 最终 E2 结果
4.1 shipping 发布门禁连续 5 次
run verdict processed drops p95/ms max/ms handoffs >500ms undrained
1 PASS 7200/7200 0 1.629 5.233 900 0 0
2 PASS 7200/7200 0 1.368 40.074 900 0 0
3 PASS 7200/7200 0 1.571 3.450 900 0 0
4 PASS 7200/7200 0 1.366 2.519 900 0 0
5 PASS 7200/7200 0 1.596 18.318 900 0 0
5/5 PASS
为刻画尾部,在 5 次之外另连续跑了 12 次(连同两轮探索性运行共 19 次独立运行)。 其中 12 次刻画运行里 p50 稳定在 0.760-1.085ms、p95 在 1.060-2.078ms、 p99 在 1.220-3.156ms,而单样本 max 在 1.796-47.412ms 之间摆动。
诚实标注:max 是 7200 个样本里的单个样本,由宿主调度与 GC 主导,不是策略属性。 本次把百分位(p95 / p99 < 10ms)作为门禁的稳定内核,同时保留任务书指定的 max < 50ms 上限并记录原始值。19 次运行中 max 最坏 47.412ms,上限利用 94.8%—— 这是已知的残余敏感度,需在后续 E2 / 真机复跑中继续观察。
4.2 legacy 对照与 no-overflow 控制组
[对照] 同形态、允许丢样
legacy/per-event-yield 971.9ms 7408 ev/s handoffs=7200 processed=7200/7200 p50=122.396 p95=148.204 p99=150.561 max=152.201 drops=0
r8fix7/bounded-burst 1013.8ms 7102 ev/s handoffs=900 processed=7200/7200 p50= 0.787 p95= 1.121 p99= 1.555 max= 9.786 drops=0
-> p95 改善 99.2%
[控制] 测试专用 8192 队列,两条路径都不丢样
legacy/per-event-yield 911.8ms 7896 ev/s handoffs=7200 processed=7200/7200 p50= 51.407 p95= 86.704 p99= 91.542 max= 93.551 drops=0
r8fix7/bounded-burst 1017.0ms 7080 ev/s handoffs=900 processed=7200/7200 p50= 0.839 p95= 1.427 p99= 2.036 max= 3.598 drops=0
-> p95 改善 98.4%;交接次数 7200 -> 900
4.3 active duration 连续 10 次
run verdict wall/ms active/ms active share
1 PASS 52.672 0.148 0.2810%
2 PASS 52.122 0.796 1.5272%
3 PASS 51.955 0.323 0.6217%
4 PASS 52.785 0.144 0.2728%
5 PASS 52.657 0.181 0.3437%
6 PASS 52.620 0.097 0.1843%
7 PASS 53.146 0.542 1.0198%
8 PASS 52.553 0.134 0.2550%
9 PASS 53.490 0.868 1.6227%
10 PASS 52.612 0.101 0.1920%
10/10 PASS;upstream wall wait 51.955-53.490ms,active 0.097-0.868ms
4.4 全量门禁
专项 E2 集合(7 模块) Ran 199 tests OK (38.462s)
Python 全量 Ran 705 tests in 60.442s OK (0 failures / 0 errors)
Swift 全量 182 tests / 3 skipped / 0 failures
站点(知识门禁 + VitePress build) PASS
git diff --check PASS
Python 全量从基线 703 变为 705:fairness 模块 17 → 19(-1 旧 steady,+3 新 benchmark)。
4.5 静态不变性
git diff <R8-Fix-7 提交>..HEAD -- MacApp/Sidecar/perfowl_collector_core 为空。 以下全部保持原值:
- realtime consumer bounded burst = 8 events / 1ms;
- Pmd3 pump fairness = 32 events / 1ms;
- ActivityTrace filter fairness = 64 messages / 1ms;
Pmd3Subscriptionqueue 容量 2048(8192 只在测试 fixture 中);- consumer drain 窗口 = 0.5s;
- Python collector 关闭预算 = 8.0s;
- Device Condition 采样间隔 = 20.0s;
- Swift Core watchdog
runtimeKind == .core ? 10 : 2; - FPS / FrameTime / P95 / Jitter / Refresh Rate 算法与
perfowl.raw-event/1。
5. 剩余 E4 门禁
本批次不关闭任何 E4 门禁。R8-Fix-7 的真机 E4 仍需验证:
- 纯 Display 会话
sourceConsumerTaskCount == 1,pmd3.device-condition.raw不在 adapter 列表中; - 纯 Display 会话
pumpQueueWait的 P95/P99 明显低于 Build 68 的 282.982ms,且> 500ms计数为 0; - 正常 Stop 时
consumerDrainStatus = completed、overallCloseoutStatus = clean; - 选中 battery/thermal 指标时条件源仍然启动,20s 间隔保持;
realtimeConsumerFairness.maxObservedBurstCount <= 8;- 真实(未压缩)120Hz 会话中总排空时间没有可测量的退化。
下一步:等待独立审计。