# 同步等待实现、历史与本轮验证

本轮Native基线为`9a5b577b77a6a87efcd8e6e218693af6faed17ce`，`native/ape.jar` SHA256为`c08fdb34321c760112383b9afc2c11360d35f01120259492ea25d39fb95ea370`。当前191个Native Java源文件逐字节等于该提交；15条Run的冻结summary均记录同一commit/JAR。保存的构建身份把该源码与该JAR关联，本次另对实际JAR反汇编核对`probeTimeoutMs`默认5000、`submitRetained`、`awaitUntil`和Witness选择调用。Java离线排序使用配套`ape-java.jar`，没有重新编译或覆盖Native JAR。身份检查见[evidence/code-identity.json](evidence/code-identity.json)、[DEX](evidence/dex/)、[既有构建回执](../../experiments/guitaboo_fixab_omni_rep2_20261105T2218/admission/platform-build-identity.json)。这不是一次新的完整Android可复现构建证明。

## 原始设计确实实现过，并保留在正式JAR中

Git提交`2763d2f18e89ea418bb22be61d26cc0042d9a211`（2026-10-31 22:42:43 +0800）增加retained late reply、独立网络生命周期和`awaitUntil`，同时增加`SemanticLateResultTest`。`855653c`（2026-11-02 18:28:10 +0800）继续做bounded review/evidence构造；冻结`9a5b577`保留这些路径。原始diff在[evidence/design-2763d2f.diff](evidence/design-2763d2f.diff)、[design-855653c.diff](evidence/design-855653c.diff)，不是仅依据commit标题判断。

既有历史测试[results.json](../../artifacts/probe-persistent-20261102/final-failopen-v3/retained/results.json)包含same/new tree复用、version/gui/candidate/history失效、网络生命周期到期和5000ms放行。该文件是历史合成测试，不是本轮正式运行证据，本任务没有重跑它。

## 三种“超时”不能混用

|配置/行为|冻结代码含义|本轮|
|---|---|---|
|`ape.jev.probeTimeoutMs`|Semantic Review caller的总prepare预算；含锁、本地Evidence/Pair、await、解析/落账检查；默认5000|10条模型Run均15000|
|`ape.jev.timeoutMs`|同步retained HTTP的网络生命周期取max(probeTimeoutMs, timeoutMs)，从submit起计|60000|
|Probe动作执行|Semantic模式中未发现独立15000ms输入执行计时器；Probe绑定后经APE原生输入/Transition确认|不能把probeTimeoutMs解释为点击执行超时|
|Gateway准入队列|当前平台另有120秒队列deadline、上游请求timeout60；不是APE caller预算|以冻结配置和真实队列记录核对|

源码：[JevRuntime.java:121–143, 492–509](code-frozen/com/android/commands/monkey/ape/jev/JevRuntime.java)（492以后是旧Probe请求分支，本轮Semantic模式不启动该worker）、[JevSemanticReview.java:118–122, 155–180, 287–309, 474–514](code-frozen/com/android/commands/monkey/ape/jev/JevSemanticReview.java)、[JevTransport.java:42–45, 75–127](code-frozen/com/android/commands/monkey/ape/jev/JevTransport.java)。`JevDeadline`是合作式检查，不能抢占任意JVM/GUI调用，因此是约束等待/检查点的软预算，不承诺全部函数硬实时毫秒截止。

## 真实调用关系与线程

1. APE动作选择调用`SataAgent.selectNewAction`：已有导航和Local Greedy优先，之后才`prepareSemanticReviews`，再选择Probe，否则Remote Greedy/Epsilon等继续。[SataAgent.java:420–469](code-frozen/com/android/commands/monkey/ape/agent/SataAgent.java)。
2. 调用Sata的APE线程进入`JevRuntime.prepareSemanticReviews`→`JevSemanticReview.prepare`→`roundPage`→Witness排序/Pair构造。该APE线程调用`await`，`providerWaitNanos`就在这段try/finally记录。[JevRuntime.java:320–360](code-frozen/com/android/commands/monkey/ape/jev/JevRuntime.java)、[JevSemanticReview.java:155–180, 615–743, 512–514](code-frozen/com/android/commands/monkey/ape/jev/JevSemanticReview.java)。
3. `JevTransport`独立`ape-probe-http`线程发送HTTP，caller用CountDownLatch.awaitUntil等待；HTTP在后台不代表本轮APE也在继续动作。Gateway排队处在这次HTTP期间，因此包含于caller等待。[JevTransport.java:42–79, 150–180](code-frozen/com/android/commands/monkey/ape/jev/JevTransport.java)。
4. caller deadline到期：保留cache到容量有限的retained map，清当轮pages/inFlight，阻止当轮语义Probe选择，fallback至普通APE分支。`selectionBlocked`只使`nextSelection`返回null，不阻止Sata后面的普通策略；没有localFailure时不抛BadState进行App恢复。[JevSemanticReview.java:173–180, 516–527, 884–887](code-frozen/com/android/commands/monkey/ape/jev/JevSemanticReview.java)、[JevRuntime.java:355–360](code-frozen/com/android/commands/monkey/ape/jev/JevRuntime.java)。
5. HTTP继续至独立网络deadline；arrival回调交给`ape-semantic-local`落`semantic-arrival-*.json`。记录`validated=false/applied=false`；后台不触碰GUI对象或写入语义决策。[JevSemanticReview.java:529–550](code-frozen/com/android/commands/monkey/ape/jev/JevSemanticReview.java)。
6. 同步模式`poll()`直接返回，不在任意safe point消费raw回复；后续真正进入prepare且有review work时，`resumeRetained`核对State对象、version、input signature、history revision、GUI identity及全候选绑定，再`consumeCache`写Ledger。异步开关是另一路径，不能与本轮混为一谈。[JevSemanticReview.java:183–229, 554–597, 767–800](code-frozen/com/android/commands/monkey/ape/jev/JevSemanticReview.java)。

源码只能确定逻辑线程角色，归档没有OS线程调度/逐锁追踪；不声称测到了所有后台CPU或线程抢占。

## 晚到回复的安全性和可用性

- caller超时不会直接取消retained HTTP；网络timeout、关闭、容量超过queueCapacity+1、失效State/version/候选会取消。
- 在另一个State进行一次满足前置条件、真正到达`resumeRetained`的审核，会立即以STALE_HISTORY_OR_VERSION取消旧State项；不是“保留到任意未来回访”。如果新State没有review work，可能尚未进入这一步。
- raw字节落盘是审计证据；运行复用依赖内存retained对象，没有查到从arrival文件在重启后恢复请求的路径。回调取消前未拿到的远端字节也不能保证最终被Native完整保存。
- 未匹配的signature/GUI可能暂留等待后续合适review；version/state/history或候选失效会丢弃/取消，而不是拿旧输入直接作当前决策。
- inFlight/pages/retained、候选key和Ledger在同scope下抑制重复；失效后允许新请求。预算更短会增加失效/再提交机会，不能宣称“绝无重复提交”。

已接受的PROMOTE使用Ledger的另一路径：[JevReviewLedger.java:222–249, 269–282](code-frozen/com/android/commands/monkey/ape/jev/JevReviewLedger.java)允许适用scope内保留pending，重新绑定和确认后EXECUTED。Statistics的1072→1201是这个路径，不是HTTP晚到。

## 本轮逐请求验证

| App | 条件 | HTTP数 | 实测await累计秒 | 回执P50/P90/P95/P99秒 | await P50/P90/P95/P99秒 | Gateway队列秒 |
|---|---|---|---|---|---|---|
| activitydiary | JEV | 243 | 699.014 | 2.806/4.697/4.785/5.005 | 2.806/4.697/4.784/5.005 | 410.307 |
| activitydiary | PURE_APE | 0 | NA | NA/NA/NA/NA | NA/NA/NA/NA | 0.000 |
| activitydiary | STARTLUX | 140 | 146.559 | 0.943/1.387/2.009/2.112 | 0.943/1.387/2.009/2.112 | 8.924 |
| odkcollect | JEV | 20 | 70.811 | 4.640/5.188/5.217/5.217 | 4.640/5.188/5.217/5.217 | 47.512 |
| odkcollect | PURE_APE | 0 | NA | NA/NA/NA/NA | NA/NA/NA/NA | 0.000 |
| odkcollect | STARTLUX | 7 | 9.873 | 1.391/2.118/2.262/2.378 | 1.391/2.117/2.262/2.377 | 0.569 |
| omninotes | JEV | 80 | 152.592 | 1.389/3.533/4.108/4.609 | 1.388/3.533/4.107/4.609 | 55.344 |
| omninotes | PURE_APE | 0 | NA | NA/NA/NA/NA | NA/NA/NA/NA | 0.000 |
| omninotes | STARTLUX | 97 | 114.423 | 1.066/1.833/1.941/2.388 | 1.066/1.833/1.941/2.388 | 7.352 |
| scarletnotes | JEV | 318 | 1273.566 | 4.779/5.175/5.234/5.376 | 4.778/5.175/5.234/5.376 | 900.873 |
| scarletnotes | PURE_APE | 0 | NA | NA/NA/NA/NA | NA/NA/NA/NA | 0.000 |
| scarletnotes | STARTLUX | 74 | 109.616 | 1.576/1.915/2.056/2.427 | 1.575/1.915/2.055/2.427 | 4.901 |
| wikipedia | JEV | 25 | 35.008 | 1.338/1.424/1.514/3.042 | 1.338/1.422/1.513/3.042 | 3.115 |
| wikipedia | PURE_APE | 0 | NA | NA/NA/NA/NA | NA/NA/NA/NA | 0.000 |
| wikipedia | STARTLUX | 26 | 35.369 | 1.054/2.051/2.545/2.688 | 1.054/2.051/2.544/2.687 | 1.777 |

完整回执P分位用Native提交→完成；实测阻塞P分位用本轮每review唯一请求的provider_wait_ns；1,030条均满足这个条件。每条都保留wait-start/consume/下一普通选择的同设备monotonic_ns、源码事件行和回执链接，见[request-waits.csv](request-waits.csv)。等待包络内普通选择为0；下一普通选择较晚可能因为先执行Probe，不能把consume到下一普通选择整段也计为Provider阻塞。

四条重点Run最长await见[longest-measured-waits.csv](longest-measured-waits.csv)：Scarlet Jev semantic-276、step1404为6.483秒（Gateway queue3.958，上游2.488）；Activity Jev semantic-246、step1633为5.186秒（queue3.892，上游1.256）；Omni Jev semantic-74、step1593为4.637秒（queue3.548，上游1.051）；Omni StartLux semantic-18、step394为3.492秒（queue0.067，上游3.378）。同Host队列/上游差值不与设备绝对时刻相减，差额包含Native传输及其他短处理，未强行命名。

## 3/5/8/10秒离线比较

| 预算秒 | 完整回执≤预算 /1030 | 完整回执>预算 /1030 | 纯await截尾量秒 | prepare完成≤预算 /1030 | prepare数值尾长秒 |
|---|---|---|---|---|---|
| 3 | 641 | 389 | 612.507 | 627 | 711.297 |
| 5 | 909 | 121 | 18.793 | 830 | 51.445 |
| 8 | 1030 | 0 | 0.000 | 1030 | 0.000 |
| 10 | 1030 | 0 | 0.000 | 1030 | 0.000 |

完整回执超过预算，与“总prepare已经结束”是不同指标；未记录每个caller deadline的精确绝对值，因此不能用网络P分位代替整个prepare预算，或精确断言反事实何时离开State。5秒网络晚回121/1030，3秒389/1030；8、10秒本轮网络晚回0。实际预算包括本地准备，5秒prepare完成的只有830/1030，3秒627/1030。State离开/后续重新审核轨迹在反事实不存在，CSV保持NA。

## 发现的集成问题：软预算耗尽会永久标不健康

`prepare` catch DEADLINE及`failOpen`设置healthy=false，prepareLocked只复位selectionBlocked/localFailure，消费成功也不恢复healthy。`JevRuntime.prepareSemanticReviews:356–360`及close:826把它转成decisionHealthy=false；RUN_FINISHED:839输出该值。当前验收实现`lab_platform/results.py:125–136`及仓库`experiment_runner.py:256–258`要求该标志为真。当前平台源码只作旁证，仓库脚本存在用户未提交修改，未触碰它。

**已有真实历史合成日志证据**：[historical-soft-timeout-health.json](evidence/historical-soft-timeout-health.json)指向原文件：第6行DEADLINE/fallback native，第11行成功消费原semantic-1，第12–14行PROMOTE，最终第28行decision_healthy=false且evidence_healthy=true；5000ms放行与复用测试本身passed。这说明“可继续APE和复用”与“正式有效性通过”不是同一件事。

如果研究目标把soft budget expiry当正常控制流，应在未来获授权后把它与传输/协议/证据失败分开计数、分开健康语义；不能仅改到5秒后沿用现有验收还承诺有效。**本轮0次DEADLINE，不回改15条已通过结果。**这项是代码与历史fixture共同支持的集成不一致，未声称是本轮吞吐损失的已触发根因。
