GUITaboo Async Throughput Root-Cause Audit
GUITaboo 异步审核失效、State 演化、路由与 APE 吞吐根因调查
数据范围是
experiments/guitaboo-rn-routing-healthfix-5app-rep2-20261109-pure20261107/
的最终 10 条有效模型 Run;没有启动实验、调用模型 API 或修改
Native。正式运行 DEX JAR
SHA-256:33c71e466eefb86177f43fdd63a070e4d1494cee79ab976cc752d1fce7f8fd54。
Q1:854 次异步提交为什么只有 9 次消费?
真实漏斗是:
| 阶段 | StartLux | Jev | 合计 |
|---|---|---|---|
| Native 异步提交 | 615 | 239 | 854 |
| 消费并进入现有处理流程 | 8 | 1 | 9 |
stale(STALE_HISTORY_OR_VERSION 复合条件) |
607 | 171 | 778 |
| HTTP 200 已到达但没有消费 | 0 | 67 | 67 |
| 异步采纳 PROMOTE | 1 | 0 | 1 |
| 异步确认 Probe | 0 | 0 | 0 |
StartLux 的 615 条中 607 条在响应消费前被
State/version/history/confirmation/exact 条件拒绝,另 8 条消费成功。Jev
的 239 条中 171 条同样 stale,67 条 arrival 归档显示 HTTP 200
但没有再次进入 consumeCache(),只有 1 条消费成功。854
条全部都保留了 request/arrival/response
原始证据;这个问题不是“后台没有返回”,而是结果没有获得合法的 Ledger
发布入口。
生命周期是
Candidate → roundPage/Pairwise Request → submitRetained → Gateway queue → arrival archive → poll/resumeRetained → consumeCache → Pairwise aggregation → JevReviewLedger.putBeforeDeadline → staged Pending Probe → executable/navigation → Native input/confirmed transition。archiveOnArrival()
明确只写 validated=false, applied=false,不会保存
Ledger。
67 条到达未消费的 Jev 结果中,原始答案均可解析并含有效 answers;例如
ODK/Jev semantic-32 是 HTTP 200、raw PROMOTE、Step
281、回调前 APE 已继续 1 次,但
stored_entries=[]。代码把“回到原 source GUI
才允许消费”写成了 resumeRetained() 的必要条件:GUI identity
不同就 continue,结果只留在 retained/arrival 证据中。
778 条 stale 的精确 OR
分支无法从现有归档拆出。consumeCache()/resumeRetained()
的硬条件是:精确 modelVersion、来源 State 对象身份、来源
ModelAction execution revision、全局 confirmation count、当前 exact
execution,以及可重定位
Concrete。归档没有记录消费瞬间每个条件的当前值或失败
bitmask,因此报告保留 UNKNOWN,不把所有版本变化误称为真实失效。
Q2:State abstraction version 是否被过度用于失效?
是,至少存在过度保守的路径,但不能把全部 778 条都归因于 version。
Model.rebuild() 在命名变化后移除受影响 State、递增 model
version、重建 Graph;新 State 用新的 Graph
前缀和对象创建。StateNamingManager 有 Naming parent-child
refinement/abstraction 边,但没有持久的旧 State→新 State lineage
表。JevRegistry.reset() 还会清理 execution
index。当前审核缓存比较的是 version 和对象/相关历史快照,而不是 lineage
+ 相关证据。
真实证据:
- ODK/StartLux
semantic-115:来源 version=16,step 457 异步提交,step 458 stale;相邻事件仍是 version 16,只发生多次prepare_reentered。这说明版本没变也会被复合条件拒绝,可能是 State object、相关 revision、confirmation 或 exact execution 条件。 - ODK/StartLux
semantic-66:source version=27,消费时观察到最高 version=30,Step 540 stale。这证明 version advance 可触发硬检查,但不证明 Concrete/Witness 已失效。
建议把 State lineage、Concrete continuity、Witness validity、Probe execution binding 分开检查。只有前 3 项确认后才把模型判断保存进 Ledger;第 4 项只决定当前能否执行 Probe。版本变化本身不应自动抹掉已有判断,但无法建立 lineage 或 Concrete 唯一重定位时仍必须拒绝。
Q3:有多少已有异步结果可以安全复用?
本轮真实自然运行中,已被证据证明可以在不放宽 Concrete 身份的情况下复用的 stale 结果为 0;没有一个 stale 结果同时具备可验证 lineage、唯一 Concrete 连续性和完整 Witness 证据。
可复用候选上界只能列为 UNKNOWN:异步 raw PROMOTE candidate aggregate 为 StartLux 152、Jev 27,其中绝大多数没有进入 Ledger;真正有执行价值的 raw PROMOTE 合计 179 个 Candidate outcome。它们不能直接算可复用,因为当前归档缺少触发 stale 的具体分支和 State lineage。受控 loopback fixture 证明“晚到 PROMOTE→Ledger/Pending→合法回访 Probe”机制可行,但不是自然 Provider 结果。
Q4:Jev 多台设备、Native 并发、Provider 并发是什么关系?
五个 App 的 Jev Run 可同时探索,Native 每个 Run 可持续提交同步/异步
retained 请求,共用 JevTransport/Gateway。Gateway
配置并发上限 4、14 RPM;最终观察到 Jev 上游峰值 1、最短发送间隔 4.303
s。这只说明共享 Gateway 的 pacing/响应把实际发送限制在
1,不能证明实验设备或 Native 层串行。
Jev Gateway queue wait 总计 22984.45 s,p50 3.20 s、p95 89.14 s、最大 119.47 s;StartLux 上游峰值 3、queue p95 0.114 s。多台设备持续提交、14 RPM 低于请求到达速率时,队列会增长,即使上游同时只发送 1 个请求。
Q5:Gateway 是否仍处理已经失效的请求?
是。最终 Jev 关联 queue timeout 147 条,其中 139 条的 fingerprint
只匹配 Native stale/主动取消请求,8 条重复 fingerprint
无法唯一归属。典型是 Omni/Jev semantic-40 和 Scarlet/Jev
semantic-24:Native 同步请求已经 stale,但 Gateway 仍在约
120 s queue deadline 才 timeout。
已失效请求是否消耗 14 RPM 必须按 sent_at 区分:queue
timeout 本身只能证明占用队列,不能算已发送;已经有 sent_at
的取消请求会消耗一次上游调用。当前系统没有在归档中为每条取消请求写出独立配额扣减,因此不能把
139 条全部换算成 RPM 浪费。
Q6:为什么 Scarlet/Jev 只有 7 次异步?
旧规则是整包 all-or-nothing:allMatchedExecuted()
只要一个 Candidate 没有 Registry 已确认跨 State Concrete
match,就同步;事件字段明确写
mixed_package_policy=any_unmatched_or_unknown_is_synchronous。
Scarlet/Jev:394 同步、7 异步;7 条异步都证明
matched_executed=true。但 394 条同步中有 236 条
candidate_count≥2,归档没有逐 Candidate A/S
票数,无法判断其中多少是混合包、纯未匹配包或
UNKNOWN。低异步数可以确定是当前“一个未匹配就整包同步”的结果,不能进一步把
394 条全部归为“匹配少”。
Omni/Jev 同样是 285 同步、40 异步,且 199 条同步包 candidate_count≥2;它与 Gateway queue 和 5 s soft timeout 同时发生。
Q7:多数决后十条 Run 有多少请求从同步变异步?
现有归档不能给出精确答案,因为 SEMANTIC_REVIEW_ROUTED
只写 request-level matched_executed,没有逐 Candidate
A/S。已生成的 routing-majority-replay.csv 对 3121
个实际请求逐条标出 EXACT 或 UNKNOWN。
对旧异步请求,A=n、S=0,反事实仍确定为异步。对旧同步且 candidate_count=1,A=0、S=1,反事实仍确定为同步。只有旧同步且 candidate_count≥2 的请求可能发生切换,必须列 UNKNOWN:
| Run | 旧同步 | 确定仍同步(candidate=1) | A/S UNKNOWN | 可能转异步的上界 |
|---|---|---|---|---|
| ODK/StartLux | 43 | 15 | 28 | 28 |
| Scarlet/StartLux | 458 | 200 | 258 | 258 |
| Omni/StartLux | 211 | 69 | 142 | 142 |
| Wikipedia/StartLux | 87 | 29 | 58 | 58 |
| ActivityDiary/StartLux | 233 | 78 | 155 | 155 |
| ODK/Jev | 181 | 61 | 120 | 120 |
| Scarlet/Jev | 394 | 158 | 236 | 236 |
| Omni/Jev | 285 | 86 | 199 | 199 |
| Wikipedia/Jev | 54 | 21 | 33 | 33 |
| ActivityDiary/Jev | 321 | 145 | 176 | 176 |
因此“Scarlet/Jev 从 7 增加到多少”以及“Omni/Jev 减少多少同步”目前都不能报精确数;可以报的证据下界是 0 个已确认切换,上界是表中 UNKNOWN 数。下一版必须把 A、S、Candidate IDs 写入路由事件后才能完成反事实。
Q8:5 秒预算是否约束了 APE 整轮?
没有。它约束的是 provider_wait_ns,不是完整 semantic
review elapsed。
全 10 条 Run 的 provider_wait_ns > 5 s 都是 0;正常 5
s soft timeout 共 768 次(ODK/Jev 77、Wikipedia/Jev 21、Scarlet/Jev
354、Omni/Jev 272、ActivityDiary/Jev 44)。但完整 review
elapsed_ns > 5 s 的次数为 768,Wikipedia/Jev 还有 1
次超过 5.5 s、1 次超过 6 s;最大为 Wikipedia/Jev Step 1146 的 7.610
s。
JevSemanticReview.await() 只累计 Provider wait;外层
prepare_total
还包括锁、证据构造、截图/本地准备、轮询、Ledger publish
和调度。若论文要声称“整轮最多 5 s”,需要把 central deadline 放到完整
prepare/consume 边界。
Q9:APE Step 与确认 Transition 的定义是什么?
Step 是每个
SELECTION_DECISION/RUN_FINISHED.step 的一次
APE 选择轮次,包含 Epsilon、Local/Remote、Navigation、Probe 等策略。确认
Transition 是有 input_confirmed=true
的实际原生输入/状态转移。Probe 如果确认输入,会同时计入 Probe 和
Transition,但不能把它再加到
Step。失败选择、未确认输入和模型请求数都不是 Step。
60 分钟 Step:Pure 12042、StartLux 9944、Jev 8154。StartLux/Jev Provider wait 总和分别为 1075.20 s、4788.86 s。可以确认同步等待与 Scarlet/Omni Step 下降同时出现,但不能把省下秒数直接等价为增加 Step;GUI/self-loop、Gateway queue、App 状态和 APE 策略也参与决定吞吐。
Q10:最小必要修改是什么?
优先级:
resumeRetained()/consumeCache():把“判断可保存”与“当前页面可执行”分开;保留 Concrete/Witness 身份和 exact execution 防线,允许通过 lineage+相关历史校验的结果先进入现有 Ledger/Pending。- 路由入口:逐 Candidate 计算 A/S,
A>S异步、A<S同步、A=S异步,并把 A/S 写入事件;不改 Pairwise/PROMOTE 和 Candidate 打包。 JevTransport/Gateway 取消:未上游发送且已 stale 的 retained call 及时释放 queue;同步请求在现有 queue 中优先;不新建调度系统。- 若需要完整 5 s 语义,再把 central deadline 覆盖 prepare/lock/consume/Ledger,而不是只限制 Provider wait。
验收必须包括:真实 854 条离线回放、A/S=0/0/1/1/2/3 的路由
fixture、semantic-32 类晚到 PROMOTE 入
Ledger、semantic-115 类无法证明 lineage 时仍拒绝、Gateway
received_at/sent_at/cancel_at 时序审计,以及 Provider wait
与 whole review 两个独立 5 s 边界测试。
更细的代码入口、验收条件和禁止范围见
minimal-fix-plan.md;逐条异步证据见
async-loss-analysis.csv。