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 + 相关证据。

真实证据:

建议把 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:最小必要修改是什么?

优先级:

  1. resumeRetained()/consumeCache():把“判断可保存”与“当前页面可执行”分开;保留 Concrete/Witness 身份和 exact execution 防线,允许通过 lineage+相关历史校验的结果先进入现有 Ledger/Pending。
  2. 路由入口:逐 Candidate 计算 A/S,A>S 异步、A<S 同步、A=S 异步,并把 A/S 写入事件;不改 Pairwise/PROMOTE 和 Candidate 打包。
  3. JevTransport/Gateway 取消:未上游发送且已 stale 的 retained call 及时释放 queue;同步请求在现有 queue 中优先;不新建调度系统。
  4. 若需要完整 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。