启动时间稳定性重评:源争用、端点独立与新来源验证门禁 ​
1. 决策摘要 ​
优先路线:先验证当前 CoreProfile 与 ActivityTrace 的启动窗口争用,再把 Total 起点从阶段配对中独立出来;首帧身份不足时保留不确定性。若上述改进仍达不到单次准确率门槛,再做 ActivityTrace 单源的启动事务/首帧身份普查。
这是一条有明确止损条件的稳定性工程路线,不是已经验证的稳定采集成果。本批只完成代码与历史记录审计、离线报告普查、合成反例验证和方案入档;产品代码保持原状,没有发起新一轮设备启动。
本次发现三件旧总结没有充分覆盖的事:
- 新架构重新引入潜在 trace 争用。 09-17 后 Display 切到 ActivityTrace,但当前普通源启动循环没有等待 Startup CoreProfile 完成 stop/drain。09-06 旧配置曾在两种系统上实测这两种 tap 争用。新配置是否仍冲突尚待 A/B;单一 DTX owner 并不自动解决设备内部 trace 资源争用。
- “Total 与中间阶段解耦”尚不彻底。 System BEGIN 在原始序列中存在,但第一阶段 END 丢失时,当前 Total 的起始 Mach tick 只从完整 span 获取,结果被误走
start-substituted。本次合成回放直接复现。 - “真实时间戳”不等于“正确端点”。 首帧 END 丢失、后续帧 END 存活时,现逻辑既可能产出普通
candidate,也可能产出frame-end-repaired。唯一存活候选只是观测集合唯一,不是物理首帧唯一。
不建议继续把大缓冲、固定预热、自动重启或“有数字就算成功”作为主攻方向。也不建议直接用整机 FrameLifetime 首事件替换目标 App 首帧。
2. 固定基线与证据范围 ​
| 项目 | 本轮范围 |
|---|---|
| 仓库基线 | main,HEAD 07a82ae0492b531321105c228c8c1df7c26fd9da |
| 工作区 | 存在用户既有未提交代码与文档;本批不纳入、不清理。审计以当前工作区为主,并在匿名证据中保存关键文件 SHA-256 与相对 HEAD 的变化状态 |
| DTX 内核 | 锁定 pymobiledevice3 11.3.1,pin commit e0dc322f4a0fa293353f8c13765516fbf15b1caa;本机 Python 环境核实安装版本一致 |
| 语义解码 | core-profile-app-lifecycle.candidate.v8,profile 和 trace-code 文件保持既有版本 |
| 历史资料 | 启动专项 devlog、docs/startup/ 调查原件、后续 Display 切源与关闭链记录 |
| 本轮执行 | E1 源码审计;E2 合成反例、94 项启动相关测试;既有设备报告的离线字段统计 |
| 本轮未执行 | 新 E4、原生 UI 操作、真实设备 A/B、吞吐/CPU/内存/I/O 改动前后基准、打包公证 |
匿名证据:JSON。只读复现脚本:Python。脚本读报告并构造合成序列,不连接设备、不修改 Session。
注意:早期记录包含“全部证伪”“唯一确定性解”等措辞。本次重新按实验实际覆盖范围判断,不把有限配置/样本的负结果外推成所有系统与全部来源的证明。
3. 当前实现链路 ​
固定版本 DTX owner
→ 设备/应用级准备
→ CoreProfile start,保留 RAW-v2 bootstrap,持续排空预热流
→ source ready → 激活有界 bridge → 一次非挂起进程冷启动
→ 启动返回目标身份前仍接收/解码 → 身份绑定 → 正式 consumer
→ 普通源启动循环(含选中的 ActivityTrace Display)
→ 两遍线程归属 + 按 Mach 时间重排 + 阶段配对
→ 普通端点 Total 或最终 repaired Total
→ completion/grace/绝对截止 → CoreProfile stop/drain → 封存
主要代码:
realtime.py::_PrelaunchCoreBridge:bootstrap、32 MiB 预热 ring、64 MiB 激活后 queue、交接期间持续消费。realtime.py::stream_candidate_session:受控启动、身份交接、普通源启动、完成等待与源关闭。launch_trace.py::_rebuild_semantics:先建立线程归属表,再重放生命周期;当前实现含排序,完整重建为 O(N log N),不是严格 O(N)。launch_trace.py::report/_pair_markers/_recover_total_endpoint:Total、九阶段、端点重配对。display_performance.py::ActivityTraceFrameLifetimeRawAdapter:新的 Display 源;scope 是foreground-device,不是目标进程首帧。
现有 source ready 表明源已产出可识别数据,并不保证后续每个目标生命周期事件都进入捕获流。lossFree 和 launchCoverageIntact 当前均由主机 live queue drop 推导,语义范围小于端到端完整性。
4. 已尝试路线:哪些保留,哪些停止重复 ​
| 历史路线 | 实际解决/发现 | 本轮判断 |
|---|---|---|
| Clock bridge、profile/mapping、精确过滤、动态归属 | 解决时钟、码表和目标归属条件 | 保留;版本变化须重验 |
| 挂起/RAW-ready/两段预热 | 开发签名 Fixture 可用于屏障实验;普通生产 App 的挂起启动曾被系统拒绝 | 作为校准条件,不作为任意 App 生产方案 |
| Build51/52 bootstrap、晚绑定保留、交接前排空 | 修复真实主机问题;历史 20 轮实时 Total 从 16/20 到 19/20 | 不回退,也不把该矩阵当成当前版本稳定率 |
| completion grace、open-phase extension | 修复过早停源,保留 15 s 绝对等待上限 | 根据真实端点/窗口关闭理由判断,不盲目延长 |
| Ready Barrier、startup-exclusive、receive/parse decouple | 当时实验未观察到阶段缺失改善 | 无新证据不原样重做;当时尚未覆盖新 Display 切源后的双 tap 组合 |
ta / bso / bsoc / bm |
基线流依赖、设备丢事件标记持续;32M/64M 配置撞 5 s ready 超时 | 不作为首选;小组 n=2–3 不足以证明提升绝对为零;主机配置回显也不是设备实际缓冲分配证明 |
| 同轮边界重建 | 共用过渡码同丢;相邻边界只给宽区间 | 不把区间中点或相邻阶段替代成精确值 |
| System Trace 旁路 | 同类 kdebug/kperf 后端且可能争 owner | 独立轮校准参考,不补当前轮丢失 |
os_trace_relay spike |
单次 25 s、132624 条日志,未见目标九阶段 signpost | 该配置未验证九阶段补齐能力;不代表另一服务 activitytracetap 的系统事务也已普查完毕 |
| Total 独立发布、repaired | 提高有值率,保留来源标签 | 保留历史事实;重新审核“精确”语义和 E4 门禁 |
| 多轮整轮择优 | 增加获得至少一份完整样本的机会 | 只作显式重复测量功能;不等于用户指定这一次成功,且会改变缓存/热状态和样本选择分布 |
源记录:状态与根因、系统性消因、缓冲实验、时钟桥与双 tap 实验、Display 切源。
5. 新发现一:当前 trace 组合存在待排除的争用窗口 ​
已确认的代码事实(E1) ​
当前 realtime.py 在身份交接后恢复 prestarted CoreProfile consumer,紧接着对 execution_adapter_types 执行 await adapter.start()。ActivityTrace 没有单独等待 startup_rotation_drain_wait_complete;Startup flush 任务在后续建立。故在 Startup + Display 同选、启动尚未完成时,存在双 tap 重叠运行的执行路径。
历史设备证据,不是本轮新 E4 ​
09-06 时钟桥实验:设备系统 A 单 owner / 双 owner、系统 B 单 owner 均出现 ActivityTrace 有行而 CoreProfile 0 records;CoreProfile 单源对照为 401517 records。它说明“不同 channel / 第二 provider”并未消除当时设备侧争用。
推论层级:优先级高的假设,而非已确认当前缺失根因。 现 ActivityTrace 使用 onlySignposts=1 等新配置,旧实验配置和当前版本不同;必须以同一新配置做对照。旧版 standalone Startup 也有缺失,所以即使争用成立,解决它也不代表全部历史缺失都会消失。
建议实验 G0 ​
同设备、同系统 build、同目标 App 版本、同受控进程冷启动协议,其他源选择保持一致:
- A:现状,Startup + Display,记录实际双 tap 生存时间。
- B:仅移除 ActivityTrace,Startup 与其余同样的源不变;隔离“增加该源”的效果,不一并关闭所有普通源。
- C:显式串行,启动期间只有 CoreProfile,完成或截止后 stop → drain → release,再启动 ActivityTrace;不进行第二次 App launch。
每个 cell 起步 30 轮(轻型/重型目标、静置后首轮/连续轮分别分层),预先随机化或交叉均衡顺序;设备温度、网络、系统后台活动、进程旧实例终止确认、是否观测到预热均记账。30 轮只作筛查,不作高可靠性声明。
记录 tapStart/firstChunk/lastChunk/stopAck/drainComplete/release、原始码计数、归属后码计数、Total provenance、失败原因、队列与设备丢失标记;数据通道沉默、设备丢失、解码缺失、UI 未显示分开统计。
若 B/C 明显提高准确 Total 成功率且复测一致,再实现中央 trace 租约/互斥状态机。不是只加一次 sleep,也不是重新运行旧“startup-exclusive”。代价明确:串行方案下 Display 在启动期间没有覆盖,必须标出 coverage gap;用户若要求二者同窗全程采集,串行方案不满足该要求。
6. 新发现二:端点仍依赖第一阶段完整 span ​
report() 的 launch_start 可回退到 _launch_start_ns,但 launch_start_ticks 只从完整 System Interface span 取值,默认 None。后续恢复又优先选择 early_start_ticks,后者来自已完成的早期阶段 span。
本次合成实验,时间基固定 1 ns/tick,完整控制序列起点 110、首帧 END 250:
| 输入变化 | 正确原始跨度 | 当前输出 | 解释 |
|---|---|---|---|
| 完整控制 | 140 ticks | 140 ticks,candidate | 控制正常 |
| 仅删第一阶段 END;System BEGIN 仍为 110 | 140 ticks | 110 ticks,start-substituted | launchStartTimestampNs=110 仍存在,但计算改用较晚 140 tick 起点 |
这不是单位误差,也不需要设备把起点重新发一次:起点在本轮数据里,计算路径丢掉了其独立作用。 当前 15 份报告的原始流未保留,因此本轮不声称该反例解释了其中多少缺失。
建议实现 G1:独立端点账本(待批准) ​
- 在生命周期事件归属成立后独立保留 System BEGIN 的 ticks、timebase、source epoch、generation、原始位置及重复起点选择依据;不等待该阶段 END。
- 保持既有重复 BEGIN/profile 规则的可追溯性,不无条件选全流最早起点;跨进程实例、断线、重新武装均隔离。
- Total 使用该账本的真实起点,九阶段仍按既有配对;缺阶段不影响已证明端点,缺真正端点不凭空补。
- 完成时一次性封存端点证据与哈希,便于区分解码器、live snapshot、封存报告、UI 四层差异。
这是可确定改善某类解码正确性的修复候选;其现实样本收益与性能仍待真实规模验证。
7. 新发现三:首帧身份的不可辨识性 ​
已有代码明确 0x31CA0006 也用于后续帧,_recover_total_endpoint 仅依据生命周期锚点后的候选数判定唯一/歧义。
| 合成输入 | 原控制序列真 Total | 当前输出 |
|---|---|---|
| code=12 保留;首个 END 250 丢失;后续 END 400 存活 | 140 ticks | 290 ticks,candidate |
| code=12 与 END 250 均丢失;仅后续 END 400 存活 | 140 ticks | 290 ticks,frame-end-repaired |
这些是 E2 可辨识性反例:不是断言每个现有 repaired 值都错,而是证明仅靠这些输入的规则不足以证明首帧身份。现有 test_mode_b_dropped_frame_end_is_not_recovered 只测试“没有任何 END”,未覆盖“真正首帧 END 丢失但后续 END 存活”。
由此修正两种推理:
- “唯一候选”不自动等于“精确首帧”;丢失后的序列也可能只剩一条后续帧。
- “最早剩余 dyld BEGIN 与真实起点只差亚毫秒”没有普适上界;System Interface 阶段本就可能很长。原始 tick 真并不让错误端点变真。
G1 的正确性门禁先于成功率门禁。 降低 missing 不能靠把歧义数值升格。保留 repaired 诊断值可以,但在准确定义的成功率中单列,未经身份和误差验证不计为精确成功。设备丢事件标记=0 同样不证明无丢失。
8. 本机现存报告普查:只作定位,不冒充稳定率 ​
2026-09-20 读取现存 15 份 launch-trace-report.json 与对应 manifest,报告文件修改日期落在 09-17~09-20:
| 指标 | 数量 |
|---|---|
| 普通 candidate Total | 5/15 |
| repaired Total | 1/15 |
| missing Total | 9/15 |
| 报告中存在 launchStartTimestampNs | 15/15 |
| 9 份 missing 中缺 Initial Frame Rendering | 9/9 |
| missing 中 grace expired / absolute max exceeded | 8 / 1 |
| 主机 liveQueueDropCount=0 | 15/15 |
| manifest 列有 ActivityTrace 且存在 Display raw | 13/15,其中 4 份 candidate、9 份 missing |
| 保留 CoreProfile 原始流 | 0/15 |
限制:不同构建、目标、选择和实验条件混杂;缺少启动报告的会话未计入;未验证每份完整 Raw hash;没有原始流重解码。初读时为 14 份,研究进行中新增 1 份;本表以随附 JSON 的 15 份冻结快照为准,复跑脚本可能读到更多会话。两份未列 ActivityTrace 的样本不足以作对照,manifest 共存也不证明实际时间重叠。6/15 是文件样本的有值比例,不是版本成功率,不构成争用因果证据。
09-15 的历史 134 份会话统计同理:100 个已有 Total + 15 个 Mode A + 2 个 Mode C = 117/134≈87.3%,是当时离线可产值/预计恢复口径。它混入替代起点和终点歧义,没有给出当前版本逐次准确成功率。
9. 如果 CoreProfile 仍达不到门槛:一条值得限定探索的新路线 ​
ActivityTrace 单源启动事务普查(G2,未验证) ​
目的不是用已有整机帧冒充目标首帧,而是查明系统是否输出带目标实例/事务关联的启动区间或首内容提交/呈现证据,例如来自系统应用生命周期、窗口场景或渲染事务的 signpost。候选名称和字段必须从设备实际 schema 得到,当前没有一个已验证 selector/事件名可以直接交付。
它与已关闭路线的区别:
os_trace_relay与 DVTactivitytracetap是不同服务;前者的九阶段负结果不等于后者所有启动事务已被排除。- 新 Display 链已证明在某些设备配置下可接收 ActivityTrace FrameLifetime;这只证明通道和该帧类型,不证明 App 启动语义。
- 当前白名单只保留
com.apple.coreanimation / IOMFBServer / FrameLifetime,其他候选在上游过滤,现存 Display 文件不适合用于“其他启动事件不存在”的结论。 - G2 先单源执行,避开已知的双 tap 风险。不计划将两条未经兼容性验证的流直接拼接。
G2 必须同时通过的五道门 ​
- 存在性:先做仅 schema/子系统/事件名计数的有界 census;有候选后才白名单保存最小字段。每轮最多 20 s,隐私日志正文零落盘,目标均匿名。
- 身份:获得 App 实例/launch transaction/scene/surface 的可验证关联;仅“目标在前台”“surface 首次出现”“同一个系统日志进程”均不够。
- 端点语义:区分启动请求、进程建立、启动画面、首业务帧和可交互;证明候选对应所宣称边界。不同定义使用独立候选指标,不悄悄复用 App Launch Total 的 metricID。
- 时钟与完整性:设备时间基动态获取;若跨时钟,先验证同设备同次启动的映射和残差,禁止 host 收包时间与设备 ticks 直接相减。独立传输不自动代表独立丢失路径。
- 准确性与代价:可控 Fixture 的已知延迟、延迟首内容/动画/多 scene/后台抢前台等负例,验证身份与边界;跨 App/系统验证后再决定产品化。
止损:两个有代表性的系统 build、轻/重目标各若干轮仍没有目标级身份或正确首帧边界,就停止 G2;不以整机 FrameLifetime、日志关键词或主机观察值填补 Total。预计 spike 1–2 工程日,不含跨版本正式验收。
其他路线的定位 ​
| 路线 | 适用性 |
|---|---|
| 官方开发测量 / 可控 Fixture | 校准与因果测试;与普通生产 App 测量条件分开 |
| MetricKit | 集成后的线上分布,不是本项目每次外部启动的即时结果 |
| 进程运行/前台观测 | 项目已有独立 Observation 指标;保留自己的单位、时钟与轮询不确定性,不替换首帧 Total |
| 视频/截图识别 | 测量的是视觉就绪且有帧采样误差,不作内核首帧或九阶段真值;本方案不引入 |
| 多轮重试 | 用户显式选择的独立轮次,报告全样本与失败率;禁止跨轮拼接、隐式二次 launch 和只挑最快轮 |
10. 公式、质量与验收合同(提案,尚未改产品) ​
Total 定义保持不变 ​
令真实 System BEGIN 为 S,同实例且语义已确认的首帧 END 为 E:
durationNs = ((E - S) × numer) // denom
TotalMs = durationNs / 1_000_000
条件:同次启动、同实例、有效正时间基、E>S、未跨 source epoch/reconnect,端点身份符合 profile;按整数 tick 差换算,内部不提前取整,展示取整不回写原始值。缺端点/身份不明/来源不支持留空;零与负值不当作成功。
若晚起点 S' > S 被替代,且 E 确实是同一真终点:T' = T - (S'-S)×numer/denom/1e6,存在向下偏差,通常缺少可证误差上界。若误用后续帧 E' > E,误差向上。两者可能偶然抵消,数值量级合理不算验证。
这里冻结的是后续修复/实验验收意图,现有 Registry、计算公式和数值发布规则保持原样;知识页同步追加本轮证据限制,不把研究提升为已验证能力。
稳定性分母与质量分层 ​
N_all:全部已接受并发起的测量请求;源未武装、launch 失败、超时、缺报告均记失败类别。显式用户取消单列,并同时报告含取消/剔除取消口径。P_numeric:有数字次数 / 请求数,只衡量有值率。P_exact:端点身份与定义满足准入条件的次数 / 请求数;未经校准的 repaired、ambiguous、substituted 不混入。P_phase:必需阶段完整率,条件回调另报;与 Total 成功率分离。- 误差:与兼容同义参考比较的绝对误差和有符号偏差 P50/P95/max。不同启动轮次只作分布对照,不当作逐轮真值。
- 及时性:设备真实端点到报告就绪、点击到源 ready、停止到进程退出分别计时。
建议验收目标(待批准):目标平台分层 P_exact≥99%;同义可控参考误差 P95≤max(5 ms,1%)、max≤max(20 ms,3%);任何错 App/错实例/错首帧算正确性失败而不是仅算误差离群。若参考测量本身没有相应精度,门禁保留开放,不编造精度。
零失败独立伯努利样本的单侧 95% Clopper–Pearson 下限为 0.05^(1/n);300/300 时约 99.006%。因此“每关键分层约 300 次零失败”才具有该统计含义;30/30 或总体混合 300/300 均不证明每平台≥99%。热状态和重复样本相关性须单列,任何有限测试均不证明未来 100%。
11. 轻量化、时限与执行计划 ​
| 项目 | 设计/预算(待测,不是实测成果) |
|---|---|
| G0 关键路径 | source ready → 单次 launch → endpoint/wait deadline → drain/release → Display;同一设备同一时刻最多 1 个受控 trace tap |
| G1 复杂度 | 独立起点账本增量 O(1)/事件;端点候选有界 K;不新增全量排序或按 UI 刷新重扫。现有完整重建排序开销单独测 |
| 内存 | 新端点审计账本预算≤8 MiB/轮;达到上限显式截断/partial,不静默淘汰后声称完整 |
| 研究 Raw | 启动窗口 full retention、建议≤512 MiB/轮硬上限,超额停取并记失败。不得将截断样本算无损;默认用户会话不转为无限 Raw 保存 |
| 时间边界 | ready 保持既有 5 s 门槛;启动绝对等待保持15 s;stop/drain 保持既有有界策略,明确 ready/launch/wait/drain 是不同计时段,15 s 不是全部流程上限 |
| 并发 | 单 DTX owner;设备内 trace 活跃流有租约,宿主解析/持久化有界队列;先验清理只针对本会话拥有的资源 |
| 吞吐 | 根据真实保存窗口 P95 ingress 设计,解码吞吐≥其2倍作为目标;持续无主机队列丢弃;不拿过滤后0.04 MiB/s当作全链传输负载 |
| 性能目标 | 端点增量处理 CPU/wall time P95 相比匹配基线回归≤5%;内存/I/O 峰值分别报告;设备端点到主结果就绪 P95≤1 s为目标,若受源批量投递限制如实保留 partial |
性能验证必须冻结旧/新两个版本、同一批全尺寸 Raw 和同设备 A/B;报告首响应、长启动、洪流、设备静默/断开、重复会话、最差时延、吞吐、CPU、RSS 和磁盘写入峰值。合成几十条事件通过不替代此门禁。
| 顺序 | 工作 | 预计投入 | 出口 |
|---|---|---|---|
| 已完成 | 文档/当前代码审计、报告普查、反例 | 本轮 | E1/E2,保留研究证据 |
| 下一批,待批准 | G0 兼容性探针与 A/B;G1 端点账本及反例测试最小修复 | 2–3 工程日 + 设备矩阵执行时间 | 定位双 tap 是否因果相关;真实样本收益、正确性、性能报告 |
| 条件分支 | G2 ActivityTrace 单源启动事务普查 | 1–2 工程日 | 有可验证目标级信号才继续,否则停止 |
| 最终准入 | 冻结平台配置后执行准确率/误差/性能矩阵 | 由样本数与静置条件决定 | 明确支持矩阵;仍有缺口则维持 candidate/partial |
回滚:每个变量独立开关、一个批次一个窄提交;可退回原始采集配置与账本发布逻辑;历史 Session 不重写;不要复活已删除的实验开关堆叠使用。
12. 本轮验证、未关门门禁与整体进度 ​
执行环境:MacApp/.sidecar-build/venv-py312/bin/python。
| 验证 | 结果 | 等级 |
|---|---|---|
unittest discover -s MacApp/Sidecar/tests -p 'test_perfowl_launch_trace.py' -q |
45/45,通过 | E2 |
unittest discover -s MacApp/Sidecar/tests -p 'test*startup*.py' -q |
49/49,通过;与上行文件集合不重叠 | E2 |
| 合成控制与三项反例 | 4 个案例输出已存匿名 JSON;反例证明当前规则的局限,不是修复已通过 | E2 |
| 既有报告只读普查 | 15 份;5 candidate / 1 repaired / 9 missing | 离线审计,非新 E4 |
| 知识门禁与站点构建 | PASS,构建完成、0 构建错误、0 死链;保留既有措辞提示与大 chunk 警告 | E2 |
| 文档与证据核对 | 研究正文/HTML 数字与冻结 JSON 一致;关键源码 SHA-256 未变化;git diff --check 通过 |
E1/E2 |
下一阶段工作:批准 G0/G1 最小实验与修复后执行,不直接继续大缓冲或多次冷启动“择优救数”。G2 是条件探索,不提前改动来源与指标名称。
整体进度:启动采集已有实际产值链路,但单次准确率、首帧身份、当前双 tap 兼容性、跨设备/系统稳定性和效率基准仍开放。此研究批次完成不代表稳定采集方案已经落地;原有原生 UI、正式签名公证/跨架构、分发合规门禁不因本轮调研关闭。