planP2E1partial2026-09-24

Build 74 Phase 2 · Lead 裁定与 Stop-drain 诊断实施方案

> Lead AI 编写;等待 Project Owner 明确批准。 本文是本批唯一实施依据,取代旧方案的准入、结果、测试与任务 B 实施条款;旧方案及其归档保留为历史提交,不回改历史读数。本文完成的是方案与静态/原始字节复核(E1,引用历史真机原始 Session),不是新包 E4 验收。实施记录须在本文按日期增量追加,不能由 Implementation AI 自判 PASS。

0. 基线、证据与不变量

项固定边界
冻结产品Build 74 产品 commit 1ec94623f3623d37be206f82e114a6b441547db5;签名测试 ZIP SHA-256 3a557cc0c0c666f90736c34fa9b633adb646a92a55ecfdae095c41f349a5dbc1。新包通过真机 E4 前不称正式验收完成。
方案输入eeee607 所提交的旧方案、R2 artifacts/build74-owner-e4-followup-20260924-1232/final-audit.md 与同目录原始证据目录;S2、T1-r1/r2/r3、T2 Session 及私有只读分析归档。旧方案当前未提交的 §15 是执行方建议,不是 Lead 批准文本。
共享工作区不碰 MacApp/Tests/1.trace/,不覆盖未跟踪的两份并行 devlog,不改原始 Session,不执行 reset/clean 或全量暂存。反事实副本与原始数据必须以 Session ID、Raw SHA-256、事件序列和算法版本区分。
产品边界无侵入;Network __aenter__、逐源失败和全局 missing 语义另批;Phase C Hybrid Total 继续 FROZEN;不调整启动命令、role 标记、CoreProfile 过滤配置、Mode A 锚点、队列/超时或任何显示指标公式。

已证、未证与纠错

  1. 已证(源码+原始字节):四轮冻结 UI 配置相同,Total 均 missing;S2/r1/r2 交付 CoreProfile 原始字节没有目标 IFR opener;r3 有目标线程的 1 条 code=12 opener、2 条 IFR closer,处于 frame-continuation / post-stop-drain,被冻结保留谓词排除。仅在离线副本翻转 role,可令 r3 配对、S2 仍 missing;其数值是反事实,不得作为真实 Total。
  2. 已证(清点脚本的准确分母):私有归档 scripts/analyze_drain_admission_delta.py 先过滤生命周期命名空间、_lifecycle_actions() 非空,随后以 _thread_pids[tid] == targetPID 过滤。其 newlyAdmissibleInFrameContinuationChunks 的 S2/r1/r2/r3 为 0/0/0/3,实际是“目标归因 actionable 清点”,不是仅按 role/phase/namespace 的预筛,更不是最终准入。任意线程 actionable 对照 S2=9、r3=31。候选数、身份通过数、闭合链记录数必须分列,不得再共用“准入增量”。
  3. 已证(源码):现有 consume() 在 target_generation=None 时不拒绝;_records 无界、_reset_semantics() 被 _rebuild_semantics() 调用;report(source_raw_sha256=…) 本身不读取 Raw,真正的重放由 derive_launch_trace_session() 创建解码器并逐事件 consume()。现有两遍 _thread_pids 是全局归因,不证明 TID 从未被别的 PID 复用。

只读容量 census:按 raw-events.jsonl 中 binary chunk 的偏移顺序重组成 RAW v2 流,四轮 trace header thread 数依次为 2828/2731/2248/2288,三类映射记录去重 tid 数依次为 563/505/573/721;把两集合简单相加作保守上估为 3391/3236/2821/3009,均低于拟设保护阈值 8192。r3 诊断候选 tid 的归因见证只有一个 PID 值且等于目标 PID。该上估只证明这四个历史样本可容纳,不是未来上界;不得直接把含非 binary 块的存储文件当作连续 kd_buf 流扫描。

  1. 未证:设备丢失 marker 的 arg1 含义、TID 重用在四轮之外的分布、drain 第二条 closer 的真实语义、设备 tick 与主机 stop 时刻同轴关系、T2 双时间轴 4.38 倍跨度的原因、与 Apple Instruments 同事件端点的一致性。sourceQuality.lossFree 只覆盖主机活线队列丢失;设备丢失 marker 是丢失片段/标记,不是被丢事件条数。
  2. 纠错:coreProfileRestartCount=0 不等于 reconnectGeneration=0;sourceEpoch 可合法不为 1,必须与本 Session 的 launch/source 基线比较;“drain 收到”不等于“设备事件发生在 tap 停止之后”;dataCompleteness=complete 是产物封闭,不代表请求指标均有样本。

四轮原始事件外层的 (targetGeneration, sourceEpoch, reconnectGeneration, sourceID) 均只有一个组合,且与各自 launch.requested.raw 一致;这是历史样本的一致性事实,不是写死其具体数值的依据。

1. 架构决定(ADR-P2-01)

决定状态:方案已定,实施待 Owner 批准。

选项正确性成本裁定
把所有 drain chunk 改标为 startup会把普通帧、其他线程与其他代际一并提升实现简单但风险高否决
直接把 r3 配对提升为 totalDurationMs / repaired缺同事件语义、设备/主机时钟桥与新包 E4,且 drain timeout/设备丢失仍在污染产品和 UI 契约D1 否决
只在最终 Raw 重放生成有界、可拒绝的生命周期诊断可保留原始证据与缺值语义,不改活线一次既有扫描+小型有界账本本批唯一允许实施的产品变化

D1:主报告与 UI 的硬边界

本批 totalDurationMs 不发布;totalQuality、totalSource、totalRepairReason、status、reason、phaseResults、requiredMissingPhases、phaseCoverageComplete、spanCount、unmatchedBeginCount、_open、_spans、_completed、_initial_frame_end_* 与冻结版逐字段相同。活线 UI 仍显示 partial/missing;最终报告可比活线多一个诊断块,但不能据此出现启动总时长或“阶段已覆盖”的展示。诊断块不得含 *Total*、*Repair*、diagnosticEndpointMs、launch→closer 毫秒值或任一可直接被 UI 当作 Total 的标量。未来开放 Total 是独立决策批次,至少需要同会话同事件端点身份、设备/主机桥与外部参照的可比证据、来源与质量标签、Swift 展示来源位、新包 E4 正负形态。

D2:时间与容量

不使用 launch_start+15s、max(startup chunk tick)、主机 stop 时间或 4 秒 drain 等待预算作设备域准入上/下界。唯一时间判定是同一时基下 closer.machTicks > opener.machTicks >= openSceneBegin.machTicks;其中严格 > 是本诊断新保守门,不是冻结 _pair_markers 的 < 比较的逐字复用。缺 timebase、非正差、tick 乱序无法重建或跨 epoch,均不给闭合诊断。

容量先按第 3 节定义的精确候选层清点四轮与合成高压,512 仅作为显式安全上限,不声称覆盖所有真实会话。超限选 A:整批诊断失效;保留 overflow/计数/原因,不保留前缀形成的 opener、closer 或数值。主机时间窗限制采集耗时,不证明条数上界。

D3:显示指标拆批与依赖

本批只做 B0 只读取证,不接线指标。B0 先以 T2 原始 1716 条帧复算主机接收轴与设备 presentation 轴、stale/host gap/refreshMultiple 分布,并核对 graphics.raw 中已有的 ios.foreground.fps 路径;仅能得到双轴差异,不能擅称时钟成因。B1(DisplayPerformanceProjector 是否为四项的唯一所有者)待 B0 与重复出数检查后另批裁定并实施;B2(显示指标具名 missing reason)须与 Device Network 的独立全局缺值语义批次对齐后另批;B3(请求指标覆盖摘要)在 B1/B2 契约稳定后另批。dataCompleteness 不改义;FrameTime 时钟取证可独立延伸,但未解决前不得提升四项质量等级。

2. A1 诊断实现契约(Owner 批准后由 Implementation AI 执行)

2.1 入口与写面

  1. 仅最终 derive_launch_trace_session() 为解码器显式启用 stop_drain_diagnostic=True,实时构造保持默认关闭。最终重放将 RawEvent 外层 target_generation/source_epoch/reconnect_generation/source_id/sequence 作为独立可选参数传给 consume();不能仅从 payload 默认值推断或硬编码 epoch 1。校验后的 manifest rawSHA256 绑定诊断来源。
  2. 在现有 kd_buf 单次扫描中,独立于 retain_record 抽取 binary ∧ role=frame-continuation ∧ phase=post-stop-drain ∧ _lifecycle_actions(record)≠[] 的记录;先记 actionableAnyThreadCount,后经身份门得到 targetActionableCount,最后链门得 acceptedEventCount。候选只存固定宽度 tuple:tick、arrival sequence、tid、debugID、必要的 args、Raw sequence、chunk/record offset;不得复制 chunk 字节或向 _records、_markers 注入。最小扫描和全量扫描的 action code 覆盖必须等价;尤其 code=12 要按 _lifecycle_actions 可接受的 func 形态检查,不能只在真机分类中写死 0x2B870030。如需补扫描 ID,只在诊断 opt-in 的局部集合补齐,不改默认活线 LIVE_LIFECYCLE_DEBUG_IDS。
  3. 主报告语义重建与诊断账本分离:_reset_semantics() 只清派生语义/可重算诊断结果,不清会话原始候选账本;target rebind、原始来源不一致或溢出使诊断账本失效。_semantic_dirty 仍只由原有 _records 改变;诊断计算在最终 report() 的 _ensure_semantics() 之后从只读快照进行。多次 report 幂等;活线 _emitted_report 早退路径不新增诊断。
  4. 不触碰 realtime.py 的 role 决策、CoreProfile 采集与 stop/drain 时序,不改变 _pair_markers()、_recover_total_endpoint()、_lifecycle_anchor_ticks()。若最终重放现有路径无法取得某项外层身份,不猜值,输出 identity-unknown 诊断拒绝原因。不得为补诊断改变主报告的 target 归因。

2.2 四道准入门与拒绝优先级

门可执行判据失败时
G1 来源Raw 已校验;binary chunk;role 与 phase 精确命中;同一个 CoreProfile sourceID。不入候选;来源缺失/不一致记 source-unknown / source-mismatch。
G2 会话身份chunk 外层 generation 存在且等于 launch generation;source epoch、reconnect generation 存在且等于 launch/source 基线,不要求数值为 1/0;target PID 有独立 launch 绑定。缺值 identity-unknown,不一致 generation-mismatch / epoch-mismatch / reconnect-mismatch;整批不给闭合诊断。现有主解码器 fail-open 行为不变。
G3 线程归属trace header+扫描到的线程映射形成诊断专用 tid→单一 PID/冲突 账本;目标 tid 必须有明确且无冲突的目标 PID 见证。一个 tid 曾映射到不同 PID 时,即使冻结全局 _thread_pids 的最终值为目标,也拒绝该 tid;映射缺值亦拒绝。thread-binding-ambiguous / thread-binding-unknown;不得用 PID 数字偶合或未证的“最终映射”放行。此法保守,可能漏掉真实链,不制造目标身份。
G4 闭合冻结主语义中同 tid 仍有 UIKit Scene Creation open begin;drain 中 1 条 code=12 opener 接续该 begin,随后同 tid 1 条 INITIAL_FRAME_END_DEBUG_ID closer 严格晚于 opener;无互相冲突的中间 transition。按 (machTicks, arrivalSequence, actionOrder) 稳定排序,较早可闭合 closer 胜出。无起点/多 opener/逆序/无 closer/中间冲突均拒绝。胜出后其余 closer 记 terminal-already-closed,不生成第二 span。

拒绝优先级:Raw/来源完整性 → 会话身份 → 容量 → 线程归属 → 链闭合。统计每层原始数与拒绝原因,避免“0”掩盖缺值。r3 的预期是目标 actionable 3、链接受事件 2、多余 closer 1;S2/r1/r2 的目标 actionable 为 0,不是承诺未来所有负向都为 0。第二条 closer 与第一条的正差为 rejectedTick − selectedTick = 296418,仅作为离线测试断言,不输出 selectedMinusRejected 反号字段。

2.3 有界内存、超限和完成性

2.4 诊断块精确合同

最终 launch-trace-report.json 可仅增 stopDrainLifecycleDiagnostics,示意字段:algorithmVersion="stop-drain-lifecycle-diagnostic.v1"、sourceRawSHA256、actionableAnyThreadCount、targetActionableCount、acceptedEventCount、rejectedEventCount、rejectReasons、diagnosticUsable、chainObservedClosed、truncated、captureComplete、drainStatus、selectedOpenerMachTicks、selectedCloserMachTicks、对应的 selected*RawSequence/RecordOffset、sourceEpoch、reconnectGeneration、targetGeneration、deviceLostEventMarkerCount、deviceLostArgSemanticsVerified=false。缺值为 null 而非 0;拒绝或超限时所有 selected 字段必须为 null。仅保留可复核的原始 tick 与归因/来源字段,不派生任何 launch→closer ms 或 IFR duration 数值。公开站点/归档不得写真实 PID、tid、sourceID 或 Session UUID;本地诊断可保留原始标识供审计。

四轮预期主报告逐字段等于冻结版(剔除本批新增诊断块和不可比的生成时间字段),r3 诊断链可闭合、S2/r1/r2 仍无闭合链;如果实际回放不符,应记录 FAIL 与原始差异,不能改预期凑数。

3. B0 只读取证合同(可与方案收口同轮执行,非产品开发)

  1. 从 T2 的已验证 Raw 读取 display.frame-lifetime.raw,记录 Session 别名、Raw SHA-256、事件数、sourceID/epoch/reconnect、算法版本与首末 sequence。原始 Session 和报告只读;输出在私有分析目录,公开文档只放匿名汇总。
  2. 在各自时间域独立计算 hostSpanMs=(max(hostReceiveMonotonicNs)−min(...))/10^6、presentationSpanMs=(max(presentationTimestampNs)−min(...))/10^6;比值仅是观察到的跨度比,不作为时钟换算系数。逐事件/相邻帧统计 host gap、presentation gap、负/零/缺 timestamp、stale host gap(按冻结 FRESHNESS_STALE_HOST_GAP_NS)、refreshMultiple。不得拿主机 Stop 时刻为设备 tick 定上下界。
  3. 分别追踪 DisplayPerformanceProjector 的五项输入、活线 camelCase 输出、_consume_metric_frame() 的 metric-ID 样本入口,以及 metric_engine.py 中 graphics.raw → ios.foreground.fps 现有路径;输出所有者冲突矩阵与五项 coverage 对账。metrics-derived.jsonl=0 不等于“所有 metric_engine 路径不存在”;T2 的 1686 个 FrameTime 样本不证明其余四项已具备发布质量。
  4. B0 结论只允许写“观察到的两轴差异、哪些路径未接线、哪些需要同事件时钟见证”。若缺时钟桥或同事件 ID,原因标 unknown;不得把 4.38 倍归因于固定设备时钟比例,也不得扩 _apply_frame_coverage.metric_map 直接出数。

4. Implementation AI 文件边界与执行顺序

须先得到 Owner 对本文的明确批准。 执行时按以下顺序,不跨批:

  1. 先对私有副本做四轮分层 census 和 B0;固定原始 SHA、候选定义、三扫描模式;若 r3 不能维持 G1–G4 或 8192 上限已不足,停止产品实现并回 Lead。
  2. A1 仅可改 MacApp/Sidecar/perfowl_collector_core/launch_trace.py 的最终重放参数、诊断账本、末尾只读投影,以及与之匹配的 Python 测试/fixture;需要新增独立小模块时先在 Implementation Update 说明最小原因,不可顺手改 realtime.py、online_report.py、metric_engine.py、Swift/UI 或站点指标口径。拒绝把候选注入主 _records。
  3. 公式/字段先按本文冻结,随后写 site/devlog/ 同文档日期化 Implementation Update,记实际文件、与本文偏差、验证命令、性能对比、E2/E4 边界与遗留项。未通过门禁写 partial/blocked,不得自宣阶段 PASS。
  4. B1/B2/B3、Device Network、Phase C 和正式 Total 发布均不在本次可实施范围。任何“为测试方便”改变 CLI 默认 kdf2/csd、UI 录制配置、drain 时限、role 或源过滤都需另获 Lead/Owner 批准。

5. 必须交付的验证矩阵(不允许预设真机事件形态)

Gate原始输入/合成边界机械断言
A-Pr3 原始字节、原 role,不改标;最小/全量/离线三模式分层计数可复算;target actionable=3、接受=2、额外 closer 拒绝=1;两个 selected tick 指向真实记录;主报告仍 totalDurationMs=null/partial;三模式诊断等价。
A-NS2、r1、r2 原始字节,各三模式无诊断闭合链;Total/phase/ignored terminal 与冻结版逐字段一致;S2 的 9 条任意线程记录不能被目标化;r1 缺 launch start 不得以 0 代替。
A-Igeneration 缺值/错值,epoch 非 1 但与本 Session 一致、epoch 不一致/缺值,reconnect 变化/缺值,sourceID 混入、PID 缺失、TID 复用/冲突合法非 1 epoch 可通过该门;其他不可信身份均 fail-closed,仅诊断失效,不改主解码器。
A-C两 closer 到达序与 tick 序相反、同 tick、多 opener、只有 closer、只有 opener、插入普通帧/其他进程事件、跨 chunk 半记录只选最早可闭合 closer;没有 opener 不构造端点;冲突拒绝;普通帧不误入;半记录复原与原 scanner 一致。
A-B候选 512/513、映射 tid 8192/8193,最小/全量/离线三模式阈值内照常;超限整批诊断 truncated=true、selected ticks=null、accepted=0;主报告不变。测试必须 PASS,不允许“允许失败”。
A-S_reset_semantics()、重复 report、target rebind、live _emitted_report、最终新解码器 Raw 回放原始候选不因语义重建消失;派生诊断可重算;rebind 不跨代;live 无新增块;final 才有;report(source_raw_sha256=…) 单独调用不冒充 Raw 重放。
A-Q设备丢失 marker、drain timeout、Raw 不完整或 hash 错lossFree 不遮蔽设备丢失;timeout 可同时有观测闭合链与 captureComplete=false;Raw 校验失败不输出闭合诊断。
B0T2 原始 1716 帧及四段滚动/静止样本(如取得)双轴计算、缺值、stale 与五项路径逐条可复算;无同事件桥则时钟原因保持 unknown,四项报告不提前出数。

真机 E4:只使用冻结 Build74 同形态 App UI 入口作为对照,核对 effectiveCoreProfileConfig 的四个生命周期过滤类别、csd=0、bm=0;CLI 默认 kdf2=[0xFFFFFFFF]/csd=128 形态一律 INVALID。新包每轮先按原始字节分类(完整链、只有 opener、只有 closer、无 lifecycle、身份缺值/冲突、溢出/timeout),再套相应判据;不得要求每轮都重现 r3 三条事件,也不得把没有正向链的轮次宣称功能已获 E4。至少一个新包真实正向闭合链、真实负向形态、原始哈希/报告一致性和活线/最终主字段对照齐备,Lead 才可考虑 A1 E4 PASS。所有会话的 Total 仍按原生契约,不因诊断提升。

6. 效率与交付门禁

7. 尚未解开的事实与下一决定

当前不能证明普通帧不会在更晚设备窗口复用相同 terminal、不能证明 T2 双轴差异的物理原因、不能从另一场 Apple trace 推定 Perfowl 同场端点一致,也不能以 deviceLostEventMarkerCount 推出具体丢失条数。A1 是诚实诊断而非启动成功率修复;若 Owner 的目标是立即发布更多 Total,必须另起证据批次,不得把本方案静默扩权。B0 完成后由 Lead 再定 B1 的所有者;Network 与 Phase C 均保持独立门禁。

当前状态:方案完成,Owner 批准 PENDING;产品实现未开始;Build74 正式 E4 验收未完成。

8. Lead Execution Gate Update(2026-09-24,Project Owner 工作流程调整)

Project Owner 已明确取消逐批审批:Lead AI 完成方案 → 给 Owner 可转发的执行指令 → Implementation AI 执行并交付 → Owner 将交付内容转给 Lead AI → Lead AI 独立验收。因此本文此前所有“等待 Owner 批准”“须先得到 Owner 明确批准”“若 Owner 批准 A1 开发”的表述,自本增量段起均仅作为已被取代的历史门禁保留,不再阻止执行;技术范围、D1/D2/D3、安全及证据门禁不变。

当前实施门禁:Lead 已完成本文并发出配套执行指令;Owner 将该指令转交 Implementation AI 即可开始。先执行 §3 B0 与 §4 第 1 项的只读取证/分层 census;若 G1–G4 对 r3 不成立、8192 保护阈值已不足、主报告不变量无法保持或性能预算预判不可达,实施方停在取证阶段并交付阻塞证据,不得自行扩大范围。若前置门通过,再实施 §2 A1、§5 全矩阵、§6 性能和交付门禁。Implementation AI 只报告实现、自测与证据,不自判阶段 PASS;Owner 转交完整交付后,由 Lead 决定是否通过及下一批方向。

实施交付必须至少包含:exact commit/parent/受控文件清单和共享工作区残留状态;四轮与 T2 的匿名化 Session/Raw SHA/输入输出清单;B0 双轴与所有者冲突矩阵;A1 主报告零差异证明、分层计数、512/513 与 8192/8193、身份/线程复用/timeout 对抗测试;专项及全量测试命令与原始输出;前后性能对比;日期化 Implementation Update、站点/新增归档与构建结果;签名/公证/stapling/安装/包 SHA 的真实状态;双远程与 Webhook 结果;仍缺的 E4 真机证据及下一阶段。任一门禁缺口如实标 partial/blocked,不以旧 Build74 包或历史 r3 回放冒充新包 E4。

Implementation Update(2026-09-24 · Implementation AI · E2)

> 关联方案:本文件(Build 74 Phase 2 唯一实施依据)。前置门(§8 / §4 第 1 项)判定 通过,已按 §2 实施 A1、按 §3 完成 B0 只读取证、按 §5/§6 执行验证矩阵与效率门禁。证据等级 E2:本段记录本地构建、测试与原始字节回放的真实结果。A1 真机 E4 未执行、新包未构建未签名未公证,阶段状态不由实施方自判 PASS;Total、质量、阶段覆盖与活线 UI 语义保持冻结。

IU-1 受控文件与基线

项值
基线(父提交)b45d15e74f4d4ec5a2434d627cb1f249bbd8997b(main HEAD,本批开工时)
产品改动MacApp/Sidecar/perfowl_collector_core/launch_trace.py,+701 / −2
仅有的两处删除from typing import …(增补 Callable);return { → report_payload: dict[str, Any] = {(为追加诊断块改名)
新增专项测试MacApp/Sidecar/tests/test_build74_a1_stop_drain_diagnostic.py(819 行,45 项)
站点改动本文件 Implementation Update 段 + site/devlog/index.md 时间线/阶段/门禁联动 + docs/architecture/ 新增归档快照
私有取证归档~/Perfowl-Local-Archive/build74-phase2-a1-diag-20260924-1830/(脚本、out/*.json、Session 只读副本;不入库)
未触碰MacApp/Tests/1.trace/、两份并行 devlog、上一轮未提交的旧方案 §15、全部原始 Session 与 .trace

IU-2 前置门(§4 第 1 项 / §8)

门判据实测判定
r3 维持 G1–G4target actionable 3、接受 2、多余 closer 拒绝 1、正差 296418 ticks逐值命中(见 IU-4)通过
8192 保护阈值足够四轮 union < 81923299 / 3148 / 2734 / 2904,conflictTidCount=0通过
主报告不变量可保持四轮冻结字段逐字段可比四轮 frozenDiffs=0(见 IU-6)通过
性能预算预判可达单次既有扫描 + 每条 O(1) + 末尾 ≤O(512 log 512)首次实测超支,定位后按实现修正,阈值未动(见 IU-7)通过

结论:不停在取证阶段,进入 A1 实施。

IU-3 四轮分层 census(out/rounds-census.json)

轮次控制actionableAnyThreadCounttargetActionableCount链层 acceptedEventCount链层拒绝minimalWhitelistGapCountrawV2ThreadCountmappingTidCountunionTidEstimateconflictTidCount
S2NEGATIVE-reference900no-opener: 00282847132990
T1-r1NEGATIVE000no-opener: 00273141731480
T1-r2NEGATIVE000no-opener: 00224848627340
T1-r3POSITIVE3132terminal-already-closed: 10228861629040

IU-4 A1 诊断块(真机原始字节,逐字段)

轮次actionableAnyThreadCounttargetActionableCountacceptedEventCountrejectedEventCountchainObservedCloseddiagnosticUsabletruncatedcaptureCompletedrainStatusselected opener / closer (machTicks)
S29000falsetruefalsetruequiescentnull / null
T1-r10000falsetruefalsetruequiescentnull / null
T1-r20000falsetruefalsetruequiescentnull / null
T1-r331321truetruefalsefalsetimeout16767974101340 / 16767975398389

T1-r3 其余可复核 locator:opener recordIndex=4118589、recordOffset=537664、rawSequence=52;closer recordIndex=4168471、recordOffset=2694848、rawSequence=53;recordIndexUnit="decoded-record-index-1-based"、recordOffsetUnit="chunk-relative-byte-offset";rejectReasons 非零仅 terminal-already-closed: 1 与 thread-binding-unknown: 28;deviceLostEventMarkerCount=10、deviceLostArgSemanticsVerified=false;sourceEpoch / targetGeneration / reconnectGeneration = 1 / 1 / 0。

IU-5 B0 只读取证(T2 轮)

IU-6 验证矩阵与命令(原始结果)

  1. 专项合成矩阵(§5 A-P / A-N / A-I / A-C / A-B / A-S / A-Q):cd MacApp/Sidecar && PYTHONPATH=. python3 -m unittest tests.test_build74_a1_stop_drain_diagnostic → Ran 45 tests … OK。
  2. 四轮主报告逐字段冻结对照:python3 scripts/a1_frozen_vs_new.py → 四轮 frozenDiffs=0、added=['stopDrainLifecycleDiagnostics']、removed=[];冻结树 hasDiagnosticKey=false、修改树 =true;结论字符串 ALL FOUR ROUNDS: frozen fields identical。
  3. 三扫描模式等价:python3 scripts/a1_three_modes.py → 四轮 minimal == exhaustive == offline 全 True。
  4. 分层 census 与 B0:python3 scripts/census_rounds.py、python3 scripts/b0_frametime.py → out/rounds-census.json、out/b0-frametime-dual-axis.json。
  5. 全量 Sidecar:cd MacApp/Sidecar && PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_*.py' → Ran 1022 tests in 124.343s / OK。
  6. Swift 现有报告/工作台回归:cd MacApp && swift test --disable-sandbox → Executed 204 tests, with 3 tests skipped。首轮与全量 Python 套件并行运行时出现 1 项未命名失败;随后 4 轮互不竞争的运行均为 0 failures(含一次单独复跑)。本批 git diff --name-only 只含 1 个 Python 文件、未改任何 Swift 源 ⇒ 不归因本批,但该次未复现失败按诚实原则记录在此。
  7. 知识契约门禁:cd site && python3 scripts/metric-knowledge-gate.py → PASS: 66 Registry contracts, Canonical ownership, versionless governance, ten-element markers, sidebar, overview, knowledgeRole governance, and rendered visual coverage。

(以上命令使用的解释器为受管 Python 3.12:/private/tmp/perfowl-core-py312/bin/python3;脚本位于私有归档 scripts/。)

IU-7 效率门禁(§6)与一次真实超支

第一次实测(交错 3 配对、min-of-N):7 项超预算 —— S2/CPU +119.9 ms;T1-r1/wall +218.0、CPU +221.9 ms;T1-r2/wall +163.4、CPU +161.6 ms;T1-r3/wall +652.3、CPU +651.5 ms(各轮预算 100 / 100 / 100 / 100 / 100 / 189.8 / 186.5 ms)。按 §6「超过即回 Lead,不自行放宽」的精神,阈值未动,改为分解成本并修正实现:

定位(成本分解探针)结论
账本输入面映射记录 96 385 / 137 027 / 113 940 / 384 131 条,其中 >99.9% 是同一个 PERF_THREAD_DATA 族(r3:383 975 / 384 131),而唯一 tid 仅约 0.6 k ⇒ 重复度约 624 倍
主因逐条映射记录的「二次解包 + 两次整数归一化 + 方法调用 + 属性加载 + frozenset 成员测试」≈ 每条微秒级
修正①复用冻结映射分支已经解包的元组,消除同一 64 字节的二次解包
修正②账本折叠收敛为唯一实现,冲突哨兵放进同一 dict ⇒ 候选判决只需一次 dict.get;rejectReasons 等可观测契约不变
修正③映射族承接改为「冻结分支内折叠 + 整块被跳过时用流式包装器」⇒ 循环体在活线与常规分块上与冻结版逐指令等同,不新增逐记录判定
修正④drain 区域预筛由两个跨步平面降为单平面 + 逐命中读类字节;未扩大冻结正则 alternation(扩大它本身会让整段扫描多花约 3.5 s / 288 MiB)

修正后(交错 5 配对、min-of-N) —— 结论:PERF: every metric within the plan §6 budget。

轮次wall Δ(min)wall 预算CPU Δ(min)CPU 预算ΔRSS(min)读 I/O
S2+59.179 ms(+4.49%)100.0 ms+59.685 ms100.0 ms−8.86 MiB0
T1-r1+27.470 ms(+1.85%)100.0 ms+33.074 ms100.0 ms−9.55 MiB0
T1-r2−4.420 ms(−0.33%)100.0 ms−1.938 ms100.0 ms−9.43 MiB0
T1-r3+180.144 ms(+4.69%)192.0 ms+176.763 ms188.8 ms−10.83 MiB0

峰值 RSS 四轮均为负增量(修改版更低),读 I/O 全 0,均在 §6 预算内。

活线路径(§6「首个 live snapshot 延迟、长会话最坏值」)——同一 Session、活线构造(emit_completed_trace=true、诊断开关保持默认关闭),交错 5 配对:

轮次首快照 Δ(min)全会话 consume Δ(min)最差单分块 Δ(min)两树活线是否含诊断块
S2+2.614 ms+14.229 ms+4.014 ms否 / 否
T1-r1−1.023 ms−11.722 ms+6.760 ms否 / 否
T1-r2−13.516 ms−17.975 ms−5.006 ms否 / 否
T1-r3+14.607 ms−10.068 ms−2.248 ms否 / 否

增量有正有负、量级与主机噪声同阶 ⇒ 活线链路未新增扫描或等待;两棵树的活线报告都不含 stopDrainLifecycleDiagnostics。

IU-8 相对方案的偏差

  1. drain 记录的发现方式:方案 §2.1 第 2 条允许「只在诊断 opt-in 的局部集合补齐 ID」。实现改为记录跨步字节平面预筛 + _lifecycle_actions 复核,按命名空间而非 debugID 白名单选择(_lifecycle_actions 对 0x1F/0x07 code-13 与 0x2B/0x87 code-90 等形态忽略低位 func,白名单会静默漏掉等价记录)。覆盖等价性由 minimalWhitelistGapCount=0 与三模式逐轮等价证明;不扩大冻结正则 alternation。
  2. 账本的承接路径:映射记录优先在冻结映射分支内折叠;整块被冻结分支跳过的分块(frame-continuation、post-publish、retain_all_records)改由流式包装器折叠。四轮三模式与 45 项测试钉住语义等价。
  3. captureComplete 口径:取 handoffDrainStatus ∈ {end-of-stream, quiescent} 为 true,timeout 为 false,且允许与 chainObservedClosed=true 并存(方案 §2.3 第 3 条)。产品从不发出字面量 "complete",早期按 =="complete" 判定会把 r3 误标,已在实现中修正。
  4. retain_all_records(审计模式)差异:该模式会把 drain continuation 记录也保留成冻结记录,从而让 code=12 opener 关闭掉 G4 要求仍然打开的 UIKit Scene Creation ⇒ 该模式报 open-start-phase-missing: 1、thread-binding-unknown: 28、accepted=0。等价性主张仅限两种产品选择模式(minimal / exhaustive / offline);该差异已在测试与代码注释中显式文档化。
  5. 账本内部表示:tid→单一 PID/冲突 由「绑定 dict + 冲突集合」改为「同一 dict 内负哨兵 + 命名镜像集合」。可观测契约(rejectReasons 与诊断块字段)逐字段不变。
  6. 测试 fixture 的 sourceID:复用产品源码中本批之前已存在的 CoreProfile sourceID 常量(3 个产品模块 + 1 个既有测试),未新增任何设备标识。按 §2.4,站点与 docs 归档不写出该值,也不写真实 tid / PID / Session UUID;原始标识只留在私有归档供审计。

IU-9 门禁状态(不自判 PASS)

门禁状态说明
前置门(§8 / §4 第 1 项)通过IU-2
A1 实现 + §5 合成/原始回放矩阵E2 完成45 专项 + 四轮零差异 + 三模式等价
§6 效率(finalizer + 活线)全部在预算内IU-7;一次真实超支已如实记录,阈值未放宽
Python 全量 / Swift/知识门禁见 IU-6Swift 一次未复现失败已记录并归因
签名 / 公证 / stapling / 独立安装 / 包 SHApartial本机当前无 Developer ID Application 身份(security find-identity -p codesigning 仅返回 iPhone / Apple Distribution / Development),无 notarytool 凭据 profile;AGENTS.md 的签名与公证门禁在本环境无法完成,冻结 Build74 内测包 SHA-256 不变
双远程推送 + 交付 Webhook见交付汇报真实结果随交付内容一并给出
A1 新包真机 E4未执行仍需新包的真机正向闭合链、真实负向形态、原始哈希/报告一致性与活线对最终主字段对照;不以历史 r3 回放或旧 Build74 包冒充 E4
Total / 质量 / 阶段覆盖 / 活线 UI保持冻结语义四轮 totalDurationMs=null、totalQuality="missing"、status="partial"、reason="lifecycle-spans-incomplete" 与冻结版逐字段相同

IU-10 站点与归档

IU-11 站点构建与归档(本段记录于构建之后)

Lead Independent Validation & A1-R1 Repair Decision(2026-09-24 · E2)

裁定:A1 的现有提交 475c541 为 REPAIR REQUIRED,不进入新包 E4;B0 的双轴观察和四轮原始字节清点可作为只读取证保留。 本段是 Lead 独立复核,不回改 IU-1~IU-11 的执行方原始读数和自测结果。Lead 复跑 Python 专项 45/45、全量 1022/1022;这些通过只证明已覆盖路径,不覆盖下列反例。Git HEAD 与两个远程 main 均核至 475c541;共享工作区其他 AI 的未提交路径和原始 Session 未触碰。

L-1 独立确认与口径更正

L-2 阻断性反例(Lead 以已提交测试 fixture 的 kd_buf 构造作只读复跑)

  1. G1/G2 整批身份不一致未失效。 在同一回放中先输入另一个 sourceID 的 drain lifecycle 记录,再输入基线 sourceID 的 opener+closer,当前诊断出现 source-mismatch=1 且仍 chainObservedClosed=true、acceptedEventCount=2。实现只给单条候选设 gate bit,未落实 §2.1 第 3 条“原始来源不一致使诊断账本失效”及 §2.2 G2“整批不给闭合诊断”。generation/epoch/reconnect 缺失或不一致也不得以后续正常候选洗白。
  2. D2/G4 缺锚点设备 tick 顺序门。 冻结 UIKit Scene Creation begin tick=150,drain opener tick=140、closer tick=200,当前仍 chainObservedClosed=true,直接违反本方案 §1 closer > opener >= openSceneBegin。只检查 _open 非空不够;须读取同线程该 open begin 的原始 machTicks 并检验同域次序,缺 tick fail-closed。
  3. G4 忽略同线程中间冲突 transition。 drain 的 opener tick=1000、再次 scene begin tick=1100、closer tick=1200,当前仍闭合;_STOP_DRAIN_ACTION_OTHER 被记录却从未参与闭合判决。现有 test_opener_must_be_the_code12_shape_not_any_begin 甚至断言额外 scene begin 后仍闭合,属于需修正的正例。相同线程从冻结 anchor 到选中 closer 之间再出现 phase-3/phase-8 竞争 transition 时,必须明确拒绝或证明它不冲突,不能静默跳过。
  4. 字段语义需收紧。 当前 captureComplete=true 仅由 drainStatus ∈ {end-of-stream,quiescent} 推出,即使有设备丢失 marker 也可能为 true。该字段名会被误解为生命周期数据完整;在本批尚未有新包消费者时,将其改为准确的 drain 终止状态字段(建议 drainEndedWithoutTimeout),或给出等价而不宣称数据完整性的命名;保持 deviceLostEventMarkerCount 独立。rejectReasons 覆盖预筛/身份/线程/链多层,而 rejectedEventCount 只计目标层,文档与测试必须明确两者不可相加。

L-3 A1-R1 唯一可执行修复边界与验收门禁

当前 Gate:A1 E2 = REPAIR REQUIRED;A1 新包 E4 = NOT RUN;Total/质量/阶段覆盖仍冻结;B0 E1 观察已接收但不授权 B1。

A1-R1 Implementation Update(2026-09-24 · Implementation AI · E2)

实施依据:本文件末尾的 “Lead Independent Validation & A1-R1 Repair Decision”(L-1 口径更正、L-2 四项阻断性反例、L-3 唯一可执行修复边界)。基线 main = 1c7570a130958987e11919c468eedc28b50ac845。本段为纯追加,不回改 IU-1~IU-11 与 L-1~L-3 的任何数字。

范围纪律:只改 launch_trace.py 的诊断 opt-in 分支、匹配的专项测试、本文件与站点/新增归档。默认 live 构造、主 _records/_spans/Total、质量、阶段覆盖、role、采集配置、FrameTime 公式、Swift UI、Network、Phase C 全部未触碰;未回改既有历史报告与归档。

R-1 实际修改(MacApp/Sidecar/perfowl_collector_core/launch_trace.py +178 / −73)

条目L-2/L-3 要求实际实现
A · 会话级身份(L-2 item 1)混合来源/代际使整批诊断失效,含被主解码器提前丢弃的 chunk 与无 actionable 的 chunk新增 _stop_drain_check_chunk_identity(),在 consume() 最前面(早于 _prefix_rejected、generation 门、_decode_chunk 的每一个 early return)对每个被消费 chunk 的外层 sourceID / targetGeneration / sourceEpoch / reconnectGeneration 与 launch baseline 比较;任一缺失或不一致即 self._stop_drain_batch_invalid = True,投影据此早期返回 diagnosticUsable=false、chainObservedClosed=false、acceptedEventCount=0、全部 selected* 为 null。原逐候选 gate bit 改为读取本 chunk 的判定结果(_stop_drain_chunk_identity_ok),因此不再存在"后续正常候选洗白前面错源"的路径
B · 严格设备域次序(L-2 item 2)closerTick > openerTick >= openSceneBeginTick;缺 anchor tick fail-closed新增 _stop_drain_anchor_ticks(tid) -> (anchor_present, anchor_ticks),从冻结语义的 _open[(tid, "UIKit Scene Creation")] 顶层 marker 读原始 machTicks;判别顺序为 无 anchor → open-start-phase-missing、anchor 存在但 tick 不可比较 → 新增 anchor-tick-missing、openerTick < anchorTick → 新增 opener-before-anchor,三者任一成立都不生成链。不用 15 s、host stop 或 chunk 最大 tick
C · 同线程竞争 transition(L-2 item 3)拒绝 anchor→closer 之间的重开 scene 与其他 phase-3/phase-8 竞争 transition,计 interleaved-conflict_STOP_DRAIN_ACTION_OTHER 首次参与判决:窗口 [anchorBegin, selectedCloser) 内除唯一 code-12 opener 与纯 IFR closer 之外的任何候选行都保守拒绝。窗口拆成两段:anchorTicks <= tick < openerTick(在候选循环前一次性判定)与 (openerTick, openerArrival) < (tick, arrival) < (closerTick, closerArrival)(逐候选判定)。原「只检查其他 IFR opener」的守卫替换为 action_mask != _STOP_DRAIN_ACTION_CLOSE_IFR
D · 字段语义(L-2 item 4)改名为准确表达 drain 终止状态的字段captureComplete → drainEndedWithoutTimeout(同一布尔值 drainStatus ∈ {end-of-stream, quiescent},但不再可被读成"生命周期数据完整");新增 rejectReasonsUnit="pre-screen+identity+thread+chain-reason-count" 与 rejectedEventCountUnit="target-layer-event-count" 两个机器可校验的单位字段;deviceLostEventMarkerCount 保持独立

新增拒绝原因 anchor-tick-missing、opener-before-anchor 已写入 STOP_DRAIN_REJECT_REASONS(词表保持封闭,rejectReasons 仍逐键自该元组生成)。

R-2 对抗 fixture 与专项测试(45 → 60 项)

MacApp/Sidecar/tests/test_build74_a1_stop_drain_diagnostic.py +285 / −13。新增 15 项,其中 L-3 点名的负例逐条落地:

新增测试断言要点
test_foreign_source_chunk_before_a_healthy_chain_invalidates_the_batchL-2 case 1 原文形态:错 source 在前 + 正常链在后 ⇒ 批失效、acceptedEventCount=0、8 个 selected 字段全 null
test_missing_source_id_chunk_before_a_healthy_chain_invalidates_the_batch缺 sourceID ⇒ source-unknown + 批失效
test_missing_identity_values_before_a_healthy_chain_invalidate_the_batch缺 sourceEpoch / targetGeneration / reconnectGeneration 三子例 ⇒ identity-unknown + 批失效
test_early_dropped_wrong_generation_chunk_invalidates_the_batch错代际 chunk 被冻结 generation 门早退 + 正常链 ⇒ 批失效
test_source_mismatched_chunk_without_actionable_records_invalidates_the_batch错源 chunk 无 actionable + 正常链 ⇒ 批失效(逐候选 gate 结构上不可能看到)
test_a_matching_envelope_on_every_chunk_still_closes负对照:同一形状但身份一致时仍闭合 ⇒ 新门不是"一律拒绝"
test_opener_before_the_frozen_scene_anchor_is_refusedL-2 case 2 原文形态:anchor=150、opener=140 ⇒ opener-before-anchor
test_opener_tick_equal_to_the_anchor_is_admissible谓词是 >=,边界 150==150 仍须闭合
test_anchor_without_a_comparable_tick_fails_closed直接单元校验 _stop_drain_anchor_ticks 三态,并把 anchor marker 去掉 machTicks 后断言 anchor-tick-missing 且不得被默认为 0
test_competing_phase3_transition_between_anchor_and_opener_is_refusedcode 23(end PHASES[3] + begin PHASES[4])落在 anchor→opener ⇒ interleaved-conflict=1
test_scene_reopen_between_opener_and_closer_is_refusedL-2 case 3 原文形态:opener 1000 / 重开 scene 1100 / closer 1200 ⇒ 拒绝
test_competing_transition_after_the_selected_closer_does_not_spoil_it反向控制:胜出 closer 之后的竞争 transition 不得把好链变成拒绝
test_r3_shape_still_yields_three_target_two_accepted_one_extra_closer正向回归:真实 r3 形态仍 3 目标 / 接受 2 / 拒绝 1 / terminal-already-closed=1
test_drain_termination_flag_never_claims_data_completenessquiescent 且设备丢失 1 次 ⇒ drainEndedWithoutTimeout=true 且 deviceLostEventMarkerCount=1;并断言块内不存在 captureComplete 键
test_reject_reasons_and_rejected_event_count_are_not_additive预筛层拒绝(thread-binding-unknown=2)而目标层为 0 ⇒ sum(rejectReasons) > rejectedEventCount,并断言两个 *Unit 字段

被修正的旧正例:test_opener_must_be_the_code12_shape_not_any_begin 原先断言「额外 scene begin 后仍闭合」,按 L-2 item 3 改为保守拒绝(interleaved-conflict=1、acceptedEventCount=0);同批把 captureComplete 的三处断言改名为 drainEndedWithoutTimeout,并给 replay() 增加 identity_per_chunk 以构造混合身份回放。

R-3 四轮原始字节正负回放与主报告冻结对照

轮次actionableAnyThreadCounttargetActionableCountacceptedEventCountrejectedEventCountchainObservedCloseddiagnosticUsabletruncateddrainEndedWithoutTimeoutdrainStatusselected opener / closer (machTicks)
S29000falsetruefalsetruequiescentnull / null
T1-r10000falsetruefalsetruequiescentnull / null
T1-r20000falsetruefalsetruequiescentnull / null
T1-r331321truetruefalsefalsetimeout16767974101340 / 16767975398389

r3 其余 locator 与 A1 完全一致:opener recordIndex=4118589、recordOffset=537664、rawSequence=52;closer recordIndex=4168471、recordOffset=2694848、rawSequence=53;rejectReasons 非零仅 terminal-already-closed: 1 与 thread-binding-unknown: 28;deviceLostEventMarkerCount=10、deviceLostArgSemanticsVerified=false;sourceEpoch / targetGeneration / reconnectGeneration = 1 / 1 / 0。

轮次Raw SHA-256(本批重放实测,与 A1 census 逐字符相同)
S22d9932ffd0561ae6cbc695342a0f53f4bc76ab8c62a5fad381572ba75a037f1f
T1-r1073eb427373439b8ae19243543794a113eebf1b25b7bfd17e78e0d7156c50865
T1-r2bc98c9fd3faf03bbb2fa7792ee2fe635ed0f6ed3f7641d262745584be8ffb718
T1-r30589cca3120288108886633942e8d045fe918b683b8227d43e1d6f9e20ad7637

对照结论(三树同机、同一不可变 Session 副本):

R-4 三模式等价、容量边界与 option A

轮次minimal == exhaustiveminimal == offline候选行 / 512唯一绑定 tid / 8192冲突 tid溢出batchInvalid
S2truetrue9 / 5122977 / 81920falsefalse
T1-r1truetrue0 / 5122888 / 81920falsefalse
T1-r2truetrue0 / 5122330 / 81920falsefalse
T1-r3truetrue31 / 5122440 / 81920falsefalse

R-5 效率门禁(§6,阈值未放宽)与活线路径

解释器受管 Python 3.12,交错 5 配对、min-of-N,同一不可变副本。§6 预算逐字沿用:wall / CPU 各 ≤ max(5%, 100 ms),ΔRSS ≤ 8 MiB。两种对照都报,因为二者回答不同问题。

对照一 · frozen(无诊断)→ ship(A1-R1) = 诊断总成本,与 IU-7 同口径:

轮次wall Δmin (ms)wall Δ%wall 预算 (ms)CPU Δmin (ms)CPU 预算 (ms)ΔRSS (MiB)判定
S2+73.986+5.44%100.0+67.884100.0+1.277在预算内
T1-r1+48.309+3.24%100.0+42.994100.0+2.105在预算内
T1-r2+11.555+0.86%100.0+12.878100.0+1.324在预算内
T1-r3+159.270+4.08%195.3+159.007191.8-0.574在预算内

对照二 · base(A1)→ ship(A1-R1) = 本次返工自身的增量:

轮次wall Δmin (ms)wall Δ%wall 预算 (ms)CPU Δmin (ms)CPU 预算 (ms)ΔRSS (MiB)判定
S2+52.970+3.84%100.0+50.593100.0+0.004在预算内
T1-r1+23.781+1.57%100.0+18.918100.0+1.805在预算内
T1-r2-29.930-2.17%100.0-25.719100.0-0.531在预算内
T1-r3-11.454-0.28%203.8-12.369200.3-0.141在预算内

结论:PERF: every metric within the plan section 6 budget at 5 interleaved pairs —— 8 组对照 × (wall, CPU, RSS) 共 24/24 在预算内。相对 frozen 的最大增量是 r3 wall +159.270 ms(+4.08%,预算 195.3 ms);相对 A1 基线的最大增量是 S2 wall +52.970 ms(+3.84%,预算 100 ms);ΔRSS 全部在 −0.574 ~ +2.105 MiB。未放宽任何阈值。 readBlocks 全 0。

活线路径(base ↔ ship,交错 5 配对):

轮次首快照 Δmin (ms)全会话 consume Δmin (ms)最差单分块 Δmin (ms)活线含诊断块
S2+1.284+2.730-3.724否
T1-r1-8.039-9.287-2.938否
T1-r2+8.288+19.143+7.040否
T1-r3-3.609-11.041-1.475否

R-6 验证命令与原始结果

  1. 专项矩阵:cd MacApp/Sidecar && PYTHONPATH=. python3 -m unittest tests.test_build74_a1_stop_drain_diagnostic → Ran 60 tests … OK(A1 为 45,本批 +15)。
  2. 四轮三树回放对照:python3 scripts/a1r1_four_round_replay.py → 四轮 baseVsShipFrozenDiffs=0 / frozenVsShipFrozenDiffs=0 / added=["stopDrainLifecycleDiagnostics"] / removed=[];结论字符串 FOUR ROUNDS: base==ship and frozen==ship on every frozen field。
  3. 三模式与容量:python3 scripts/a1r1_three_modes_and_capacity.py → 四轮 minimal == exhaustive == offline 全 True;THREE MODES: minimal == exhaustive == offline on all four rounds; capacity headroom unchanged。
  4. §6 效率:python3 scripts/a1r1_perf_interleaved.py 5 → PERF: every metric within the plan section 6 budget at 5 interleaved pairs (frozen->ship and base->ship)。
  5. 活线延迟:python3 scripts/a1r1_live_latency.py pair 5 → 上表;两树活线均无诊断块。
  6. 全量 Sidecar:cd MacApp/Sidecar && PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_*.py' → Ran 1037 tests in 123.316s / OK(A1 为 1022,本批 +15)。
  7. Swift:cd MacApp && swift test --disable-sandbox → Executed 204 tests, with 3 tests skipped and 0 failures(本批未改任何 Swift 源)。
  8. 知识契约门禁:cd site && python3 scripts/metric-knowledge-gate.py → PASS: 66 Registry contracts …。
  9. 站点构建:见 R-6b。

R-6b 站点构建与新增归档

> python3 scripts/metric-knowledge-gate.py && bash scripts/sync-archive.sh
[metric-knowledge-gate] PASS: 66 Registry contracts, Canonical ownership, versionless governance, ten-element markers, sidebar, overview, knowledgeRole governance, and rendered visual coverage
public/archive/.DS_Store
[sync-archive] docs/ -> public/archive/ (265 files)
✓ building client + server bundles...
✓ rendering pages...
build complete in 98.68s.

R-7 相对方案的偏差(逐条,均为实现细节,不改语义)

#方案/Lead 要求实际做法原因
1会话级失败优先(L-3)删除了 _stop_drain_scan / _stop_drain_observe 上已无消费者的 4 个身份形参,并删除冻结 generation 门里那条重复的 generation-mismatch 计数身份判定已上移到 chunk 级;保留旧计数会让同一 chunk 被计两次,破坏"分层计数"的准确性
2拒绝原因保留新增 anchor-tick-missing、opener-before-anchor 两条,而非复用 open-start-phase-missing / non-monotonic-terminalL-3 要求"明确拒绝"且"保留精确原因";复用它因会让 Lead 无法区分 anchor 缺失与 anchor tick 不可比
3"文档与测试必须明确两者不可相加"(L-2 item 4)除文档化外,额外新增 rejectReasonsUnit / rejectedEventCountUnit 两个字段让"不可相加"成为机器可校验的契约,而不是只靠读者记住一句话
4同线程竞争 transition 拒绝(L-3)窗口实现为 [anchorBegin, selectedCloser) 两段(anchor→opener、opener→closer)L-3 点名的负例里包含"scene reopen 位于 anchor→opener",只查 opener 之后会漏掉它
5不改阈值STOP_DRAIN_CANDIDATE_CAPACITY / STOP_DRAIN_THREAD_BINDING_CAPACITY / 冻结正则 alternation / _matching_record_offsets 全部逐字节未动直接遵守"超过即回 Lead,不自行放宽"
6活线不得改变新逻辑全部包在既有 if self._stop_drain_enabled: 之内;_stop_drain_identity_seen(原为只写不读的死状态)改在 chunk 级记录被观察到的身份三元组保持活线逐指令不变,同时把死状态变成有意义的审计面
7性能口径探针改用 maxRssBytes / deltaMinMiB 并注释单位见 R-5:macOS ru_maxrss 为字节;上一轮字段名有误导(未回改旧归档)

R-8 遗留项与门禁状态

Lead Independent Validation & A1-R2 Repair Decision(2026-09-24 · E2)

裁定:f54afee 的 A1-R1 修复解决了 L-2 原三项反例,但 A1 E2 仍为 REPAIR REQUIRED,不进入新包 E4。 本段只追加 Lead 新验证结论,不回改 R-1~R-8 的执行方数据。Lead 核对 exact parent=1c7570a、提交范围恰为 5 个本批路径、GitLab/GitHub main 同为 f54afee、共享工作区其他 AI 的 4 个路径未动;独立复跑专项 60/60 与 Sidecar 全量 1037/1037。四轮已验证 Raw 副本独立回放仍为 r3 31/3/2/1、链闭合,S2/r1/r2 无目标闭合链,四轮 Total 均 missing/partial;这证明历史样本不误伤,不能证明 G4 对其他线程形态安全。

V-1 独立对抗结果与根因

  1. 跨目标线程误配(阻断):同一个 launch/epoch/source 中,冻结 scene begin 和 drain code-12 opener 在目标线程 A,另一个有独立目标 PID 映射见证的线程 B 仅有 IFR closer。当前诊断 targetActionableCount=2、acceptedEventCount=2、chainObservedClosed=true、无拒绝原因。源码 closers=[row for row in target_rows if row[4]==CLOSE_IFR] 未约束 row[2]==opener[2],违反 §2.2 G4 的“同 tid closer”。不能把两个目标线程拼成一条生命周期链。
  2. 其他目标线程误阻断(同一根因的负向):线程 A 有完整 opener/closer,线程 B 在两者之间出现 scene begin;当前报告 interleaved-conflict=1 且链不闭合。G4 冲突只可检查 opener 所属线程,其他目标线程的 action 不应成为该链的冲突证据。目标进程身份相同不等于线程相同。
  3. 同 tick 的中间竞争事件漏判(阻断):线程 A 的 scene reopen 与 opener 均 tick=1000,reopen 的到达序先于 opener,closer tick=1200;当前仍 chainObservedClosed=true。R1 的前窗 < openerTick 与后窗 (openerTick,arrival) 均跳过了“同 tick 且先到达”的 reopen。设备 tick 不能给这两条事件证明安全先后,应保守拒绝;同 tick 于 closer 的竞争 transition 同理需要明确 fail-closed 规则。

V-2 A1-R2 最小修改合同

当前 Gate:A1-R1 原反例修复已验证;A1 E2 = REPAIR REQUIRED(新增 G4 同线程/同 tick 反例);新包 E4 = NOT RUN;D1/D2/D3、Network 单批与 Phase C FROZEN 均不变。

A1-R2 Implementation Update(2026-09-25 · Implementation AI · E2)

按本文件末尾 Lead Independent Validation & A1-R2 Repair Decision(V-1/V-2) 执行的最小返工。范围仅 Stop-drain 诊断的 G4 投影与匹配 Python fixture:默认活线、Raw 扫描/保留、chunk 身份门、线程映射账本、role、采集配置、Total、Swift/UI、Network、FrameTime B1/B2/B3、Phase C 一律未动;两个容量常量与 §6 性能预算未放宽。共享工作区其他 AI 的 4 个未提交路径与 MacApp/Tests/1.trace/ 全程保全。

R-1 实际修改(launch_trace.py +55/−34,3106 → 3232 行中的诊断投影段)

#Lead V-2 要求实际修改
Aopener 与选中 closer 必须同一 TIDclosers 过滤从"全部目标层行"改到"唯一 opener 确定后、row[2] == opener_tid 的纯 IFR closer";线程 B 的 closer 既不能闭合 A 的链,也不计入 A 的 terminal-already-closed
B其他目标线程的事件不拼链、不阻断interleaved-conflict 竞争判定加 other[2] == opener_tid 约束——同进程身份 ≠ 同线程,线程 B 的任何 action 都不是线程 A 链的竞争证据
C同 tick 竞争保守拒绝竞争窗口从 A1-R1 的两段开区间改为闭区间 [anchorTick, candidateTick]:与 opener 或候选 closer 同 tick 的非 opener/非纯 closer transition 一律计 interleaved-conflict 并拒绝该候选;tick 严格更晚于选中 closer 的 transition 不误伤;(tick, arrivalSequence) 仅作稳定排序,不作为同 tick 安全先后的证据
D字段契约新增 offThreadTargetRecordCount(opener 线程之外的目标层记录数)与 offThreadTargetRecordCountUnit,targetActionableCount 仍为身份/目标 PID 层总数——其他目标线程的未入链记录被显式计数,不伪装成已接受

未改动(逐字节):STOP_DRAIN_CANDIDATE_CAPACITY=512、STOP_DRAIN_THREAD_BINDING_CAPACITY=8192、_stop_drain_check_chunk_identity、_stop_drain_lifecycle_offsets、_stop_drain_fold_mapping_stream、_matching_record_offsets、_stop_drain_note_binding*、_stop_drain_fold_binding、_stop_drain_anchor_ticks、derive_launch_trace_session。

R-2 对抗 fixture(测试 +198/−0,60 → 67 tests)

新增 second_thread_witness() helper(同 PID 异 tid 的 G3 映射见证)与 7 项测试,每项同时断言 selected locator、accepted/rejected 与原因:

#V-2 场景断言
1A opener + B closer(两线程均有目标 PID 见证)targetActionableCount=2、offThreadTargetRecordCount=1、no-closer=1、不闭合、closer locator 全 None、terminal-already-closed=0
2B closer tick 更早(1100)、A closer 更晚(1200)必须选 A:selectedCloserMachTicks=1200、interleaved-conflict=0、闭合
3A 完整链 + B 中间 scene transition(1100)A 仍闭合,B 的 action 不阻断、offThreadTargetRecordCount=1
4A 内 scene reopen 与 opener 同 tick(1000),到达序前/后(subTest ×2)均拒绝:interleaved-conflict=1、acceptedEventCount=0、opener/closer locator 全 None
5A 内竞争 transition 与候选 closer 同 tick(1200),到达序前/后(subTest ×2)均拒绝:interleaved-conflict=1、closer locator None
6opener/closer 之后 tick 严格更晚的 transition(1300 > 1200)不误伤:闭合、selectedCloserMachTicks=1200、locator 完整
7字段契约(4 目标行、2 落在 B 线程)targetActionableCount=4、offThreadTargetRecordCount=2、acceptedEventCount=2、Unit 字段存在且 offThread < target

旧 60 项全部原样通过(含 L-2 三项负例、r3 形状、容量边界 512/513、8192/8193 option A、三模式等价与 hash-bound 回放)。

R-3 四轮三树原始字节回放(a1r2-four-round-replay.json,failures: [])

frozen=b45d15e7(无诊断)/base=f54afee(A1-R1,产品码与 A1-R2 基线 3c94f19 逐字节相同,sha256 935b362d… 已由脚本断言)/ship=A1-R2。每轮 baseVsShipFrozenDiffs=0、frozenVsShipFrozenDiffs=0、新增键仅 stopDrainLifecycleDiagnostics、removed=[];冻结树四轮均无诊断键;四轮 rawSHA256 与 census 期望逐轮相等。

轮次rawSHA256base↔ship 冻结差异any/target/accepted/rejected/offThread链闭合
S22d9932ffd0561ae6…09 / 0 / 0 / 0 / 0否
T1-r1073eb427373439b8…00 / 0 / 0 / 0 / 0否
T1-r2bc98c9fd3faf03bb…00 / 0 / 0 / 0 / 0否
T1-r30589cca312028810…031 / 3 / 2 / 1 / 0是

r3 逐字段复现 A1-R1:opener/closer tick 16767974101340/16767975398389、recordIndex 4118589/4168471、rawSequence 52/53、非零原因 {'terminal-already-closed': 1, 'thread-binding-unknown': 28};S2 仍 any=9/target=0(thread-binding-unknown: 9),r1/r2 仍 any=0。四轮 offThreadTargetRecordCount=0——真实四轮采集没有第二个目标线程的 actionable 记录,新门未误伤任何历史样本。

R-4 三模式等价与容量(a1r2-three-modes-and-capacity.json,failures: [])

轮次minimal==exhaustive==offline候选行 / 512绑定 tid / 8192冲突 tid溢出
S2等价9 / 5122977 / 81920否
T1-r1等价0 / 5122888 / 81920否
T1-r2等价0 / 5122330 / 81920否
T1-r3等价31 / 5122440 / 81920否

batchInvalid=false、ledgerInvalid=false、bindingOverflow=false 全四轮成立;容量边界 512/513 与 8192/8193 option A 由专项测试钉住,常量未动。

R-5 效率与活线(交错 5 配对,failures: [],24/24 在预算内)

轮次对照wall Δmin (ms)wall 预算CPU Δmin (ms)ΔRSS (MiB)readBlocks
S2frozen+16.434 (+1.19%)100.0+15.400+1.5200
S2base-4.957 (-0.35%)100.0-6.453+2.7930
T1-r1frozen+43.121 (+2.91%)100.0+44.109+1.7970
T1-r1base+23.234 (+1.55%)100.0+19.295+2.8090
T1-r2frozen+31.269 (+2.35%)100.0+26.767+2.7730
T1-r2base-8.405 (-0.61%)100.0-10.650+0.5700
T1-r3frozen+186.624 (+4.86%)192.0+174.992-0.5390
T1-r3base-19.717 (-0.49%)202.3-21.084-1.2460

预算规则不变(|Δ| ≤ max(基线 min 的 5%, 100 ms),RSS ≤ +8 MiB)。frozen→ship 最差 r3 wall +186.624 ms(+4.86%,预算 192.0);base→ship 四轮全部在 −19.717 ~ +23.234 ms。RSS 字段名在本批探针中更正为 maxRssBytes(macOS ru_maxrss 单位是字节;值一直正确,A1-R1 归档不回改)。

活线(base↔ship,5 配对;诊断默认关闭,按活线构造驱动):

轮次首快照 Δmin (ms)全会话 consume Δmin (ms)最差单分块 Δmin (ms)活线含诊断块
S2-0.544-2.558-1.935否
T1-r1+6.996-9.747-3.098否
T1-r2-12.137-12.141-4.770否
T1-r3+4.439+49.594+4.505否

最大差值(首快照 +6.996 / 全会话 +49.594 / 最差单分块 +4.505 ms)与主机噪声同阶;两树活线报告均不含 stopDrainLifecycleDiagnostics。

R-6 验证命令与原始结果

  1. 专项矩阵:cd MacApp/Sidecar && PYTHONPATH=. python3 -m unittest tests.test_build74_a1_stop_drain_diagnostic → Ran 67 tests … OK(A1-R1 为 60,本批 +7)。
  2. 四轮三树回放对照:python3 scripts/a1r2_four_round_replay.py → 结论字符串 FOUR ROUNDS: base==ship and frozen==ship on every frozen field; only stopDrainLifecycleDiagnostics added.
  3. 三模式与容量:python3 scripts/a1r2_three_modes_and_capacity.py → THREE MODES: minimal == exhaustive == offline on all four rounds; capacity headroom unchanged.
  4. §6 效率:python3 scripts/a1r2_perf_interleaved.py 5 → PERF: every metric within the plan section 6 budget at 5 interleaved pairs (frozen->ship and base->ship).
  5. 活线延迟:python3 scripts/a1r2_live_latency.py pair 5 → 上表;两树活线均无诊断块。
  6. 全量 Sidecar:cd MacApp/Sidecar && PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_*.py' → Ran 1044 tests in 119.817s / OK(A1-R1 为 1037,本批 +7)。
  7. Swift:cd MacApp && swift test --disable-sandbox → Executed 204 tests, with 3 tests skipped and 0 failures(本批未改任何 Swift 源)。
  8. 知识契约门禁与站点构建:见 R-6b。

R-6b 站点构建与新增归档

> python3 scripts/metric-knowledge-gate.py && bash scripts/sync-archive.sh
[metric-knowledge-gate] WARN: 42 content-risk audit hit(s), manual confirmation required
[metric-knowledge-gate] PASS: 66 Registry contracts, Canonical ownership, versionless governance, ten-element markers, sidebar, overview, knowledgeRole governance, and rendered visual coverage
[sync-archive] docs/ -> public/archive/ (267 files)
✓ building client + server bundles...
✓ rendering pages...
build complete in 94.36s.

(WARN: 42 content-risk 为既有 site/knowledge/** 内容告警,A1-R1 批次已披露,本批未触碰该目录,门禁最终判 PASS。)

R-7 相对 V-2 的偏差(逐条)

#V-2 要求实际做法原因
1基线 = 3c94f19base 树复用 /tmp/perfowl-ship-a1r1(= f54afee 产品码)3c94f19 是 docs-only 提交,git diff --name-only f54afee 3c94f19 仅触及 docs/ site/ internal/;两树 launch_trace.py sha256 同为 935b362d…,回放脚本对该哈希做了机器断言而非采信提交信息
2同 tick 的"到达序前后"分别拒绝用 subTest 在同一测试内构造两种到达序到达序仅影响 (tick, arrivalSequence) 稳定排序,判定本身只看 tick——两种序必须同判,分开写测试会暗示到达序参与了判决
3"清晰解释其他目标线程的未入链记录"除 offThreadTargetRecordCount 计数外,另加 offThreadTargetRecordCountUnit 字段与 A1-R1 的 *Unit 契约一致,让"目标层总数 ≠ 已接受数"成为机器可校验契约
4(fixture 构造)second_thread_witness 的 ticks 缺省 160(> 前缀末 tick 150)Raw-v2 前缀定位器要求单调 tick 序;witness 乱序会让整个 chunk 被冻结路径拒绝,诊断正确地报空账本——若不约束,所有跨线程断言会退化为空洞通过(已写入 helper docstring)
5性能口径探针 RSS 字段名 maxRssKb → maxRssBytes延续 A1-R1 R-5 的单位更正;探针属私有归档非产品代码,A1-R1 归档 JSON 不回改

R-8 遗留项与门禁状态