[Docs] (Disaggregated): plan P5c - audit the inproc split's remaining direct cross-role memory access (59 sites at a79a0af6) and schedule its zeroing before P6 as texture staged shadow, SEG_EVENT producers, handle-keyed resolution, control records, residual-value records and role guards

This commit is contained in:
2026-09-17 00:51:40 -04:00
parent a79a0af69d
commit 11ac3de6f9
4 changed files with 81 additions and 10 deletions
+7 -1
View File
@@ -561,7 +561,13 @@ client 表(`Client/EmitTables.cpp`)把后端函数表的 71 个槽分成三
- **draw 家族**19 个索引 / 实例 / multi-draw / indirect 槽全部下沉到 `draw_vbo`;用户索引 span 的 shape/extent 门在 encoder / decoder / sink 三端共用(单 range、宽度 1/2/4、`Uint64(Count) × IndexSize ≤ Size`)。 - **draw 家族**19 个索引 / 实例 / multi-draw / indirect 槽全部下沉到 `draw_vbo`;用户索引 span 的 shape/extent 门在 encoder / decoder / sink 三端共用(单 range、宽度 1/2/4、`Uint64(Count) × IndexSize ≤ Size`)。
- **sync**`FenceSync` / `ClientWaitSync` / `GetSyncStatus` / `WaitSync` / `DeleteSync` 五条现有 opcode 接线,client 铸造 Fence 句柄,wire 只过 `{slot,gen}`native fence 归 apply 线程;顺带修掉 `MGL_BACKEND_SLOT_PTR_LOCAL` 对 split 恒返回 nullptr。 - **sync**`FenceSync` / `ClientWaitSync` / `GetSyncStatus` / `WaitSync` / `DeleteSync` 五条现有 opcode 接线,client 铸造 Fence 句柄,wire 只过 `{slot,gen}`native fence 归 apply 线程;顺带修掉 `MGL_BACKEND_SLOT_PTR_LOCAL` 对 split 恒返回 nullptr。
- **具名 blit**`BlitNamedFramebuffer` 经作用域化 client-shadow read/draw 绑定发布,降为现有 bound backend 调用,退出恢复公开绑定。**GLES mip storage**:前端先定义并发布层级,server 只验证 applier descriptor 的 Levels/extentregistry 身份解析只 Find 不 mint。 - **具名 blit**`BlitNamedFramebuffer` 经作用域化 client-shadow read/draw 绑定发布,降为现有 bound backend 调用,退出恢复公开绑定。**GLES mip storage**:前端先定义并发布层级,server 只验证 applier descriptor 的 Levels/extentregistry 身份解析只 Find 不 mint。
- **P5b 留下的 inproc 依赖P6 必须替换**:具名 blit 的 scoped client binding + barriermip descriptor 的 barrier-held registry 查询;FBO death 的 inproc mailbox。三者跨地址空间都不成立。 - **P5b 留下的 inproc 依赖**:具名 blit 的 scoped client binding + barriermip descriptor 的 barrier-held registry 查询;FBO death 的 inproc mailbox。三者跨地址空间都不成立——它们只是 §17.6 清单里的三行
### 17.6 `inproc` 仍经共享地址空间的访问,与 P5c 的形状(计划,未实现)
P5 / P5b 的 wire 只覆盖 verb 记录、`SEG_STAGE` blob、reply 与 caps 快照。对 `a79a0af6` 的只读静态审计(`ROADMAP.md` "P5c 计划",报告 `~/w7/notes/p5c/p5c-audit-v1.md`)列出 59 处仍靠 verb barrier 与同一地址空间才正确的直接访问,最重的四类:**纹理纹素**虽已过 `SEG_STAGE` 但 applier 丢掉指针、Espryt 回读 client 的 `MipmapStorage`(整个纹理家族不在 `FieldOwnership.def``rsp` / strict / audit 都看不见);**反向通道**是 apply 线程直接调进 client `MG_State``OnBufferWriteback` 传裸指针,`SEG_EVENT` 已铺好但零 producer,十个回调只装了两个);**server 用前端 `GetLifetimeId()` 去 client 的 slot 分配器查找甚至铸造句柄**,而记录里其实已带句柄;**Magma** 直接读 client 的 caps 镜像、直接 `MarkGpuWritten`、直接写 client 的 mip 存储。
P5c 的设计决定:(1) **server 端纹理 staged shadow**——`ApplyTextureUpload` 采纳 `SEG_STAGE` 字节,`SyncMipmapsToBackend` 只读它与描述符,`0xDD` audit 因此覆盖纹理;(2) **`SEG_EVENT` 成为唯一反向通道**——`OnBufferWriteback``MGPBlobRef` 约定 `Seg = kSegEvent``OnGpuWritten` / `OnSurfaceChanged` 走同一 ringMagma 与 Espryt 共用回调,溢出策略按 §11.7;(3) **sink 与 twin 按记录里的句柄解析**`GetOrCreate(MGPipeHandle)`),server 永不触 `MGPipeSlots()`(4) **两条控制记录** `applier_reset`make-current 边)与 `object_death`framebuffer 首次有 delete opcode),mailbox 只剩 EGL forwarder 给 P6(5) **值类 BARRIER-PULLED 行改为每 verb 残余值记录或 server 自答**,对象类行保持 barrier 直到 twin 表落地(P3b/P4b、P7、P8);(6) **角色守卫**——split 构建有传输时,apply 线程触前端对象表面、GL 线程触 server 状态表面都是 `Fatal{RoleViolation}`;这是 P5c 的出口门,也是 P6 只做传输替换的前提。
## 附 A:开关 ## 附 A:开关
+9 -5
View File
@@ -9,7 +9,8 @@
| P0 / P0.5 / P1 / P2 / P3a / P4amonolith 跑道) | 已落地 | `ROADMAP.md` 阶段表;`MEASUREMENTS.md` §1–§5 | | P0 / P0.5 / P1 / P2 / P3a / P4amonolith 跑道) | 已落地 | `ROADMAP.md` 阶段表;`MEASUREMENTS.md` §1–§5 |
| **P5** 首个 IPC 帧(reduced pathlockstep inproc | 已收官 | `ff2994d9..37fc4fdb``MEASUREMENTS.md` §6 | | **P5** 首个 IPC 帧(reduced pathlockstep inproc | 已收官 | `ff2994d9..37fc4fdb``MEASUREMENTS.md` §6 |
| **P5b** inproc 下的 verb 迁移(Minecraft 优先) | **已收官(2026-09-16** | `37fc4fdb..82683d4a``MEASUREMENTS.md` §7 | | **P5b** inproc 下的 verb 迁移(Minecraft 优先) | **已收官(2026-09-16** | `37fc4fdb..82683d4a``MEASUREMENTS.md` §7 |
| P6 spawn transport | 未开始 | 设备出口已完成,可以开始 | | **P5c** `inproc` 共享内存读点归零 | **已审计、已计划(2026-09-17),未开始** | 审计 `~/w7/notes/p5c/p5c-audit-v1.md`59 行,头 `a79a0af6`);计划 `ROADMAP.md` "P5c 计划";设计 `ARCHITECTURE.md` §17.6 |
| P6 spawn transport | P5c 之后 | 届时只是传输替换 |
## 2. 当前头实测 ## 2. 当前头实测
@@ -57,7 +58,7 @@
| MagmaDirectVulkansplit compute/image 路径:89 个错答中 82 个 | `p5b-results/i1-v1.md` | | MagmaDirectVulkansplit compute/image 路径:89 个错答中 82 个 | `p5b-results/i1-v1.md` |
| rd12 GLES `InitialBytesNotCarried/resource_respecify`、rd12 VK `BarrierTimeout/Present``iris-bsl-esc-menu-854` GLES、三条 `texture-remint-pull` 仿真槽、`create-indirect` VK 内存膨胀 | 79 trace 普查 `counts.json` / `trace-transitions.json` | | rd12 GLES `InitialBytesNotCarried/resource_respecify`、rd12 VK `BarrierTimeout/Present``iris-bsl-esc-menu-854` GLES、三条 `texture-remint-pull` 仿真槽、`create-indirect` VK 内存膨胀 | 79 trace 普查 `counts.json` / `trace-transitions.json` |
| RGB 三通道 CPU mip 回退仍是具名 Fatal | `p5b-results/mip-codex-v1.md` | | RGB 三通道 CPU mip 回退仍是具名 Fatal | `p5b-results/mip-codex-v1.md` |
| P5b 的 inproc 依赖:具名 blit 的 scoped client binding + barrier、mip descriptor 的 barrier-held registry 查询、FBO death 的 inproc mailbox | P6 必须替换(`ROADMAP.md` 债务表 | | **`inproc` 仍有 59 处不经 wire 的直接内存访问**(2026-09-17 审计):纹理纹素已过 `SEG_STAGE` 却被 applier 丢掉、Espryt 回读 client `MipmapStorage`(整个纹理家族不在 `FieldOwnership.def``rsp` / strict / audit 看不见);反向通道是 apply 线程直接调进 client`OnBufferWriteback` 传裸指针,`SEG_EVENT` 零 producer,十个回调只装两个);server 用前端 `GetLifetimeId()` 查 / 铸 client 的 slot 分配器(记录已带句柄);Magma 四处直读 client caps 镜像、直接 `MarkGpuWritten`、直接写 client mip 存储;`MGPipeApplierReset` 与对象死亡经裸指针跨角色;`InBarrierWait` 从未接线。P5b 记下的三处 inproc 依赖只是其中三行 | `~/w7/notes/p5c/p5c-audit-v1.md``ROADMAP.md` "P5c 计划"T1A1 清单、包、出口门 |
| 27 个 P5 inproc 错答:22 纹理读回走 client-shadow 回退、3 query、1 inspection、1 FBO/RBO 删除后生命期 | P4b / P7 / P6 债 | | 27 个 P5 inproc 错答:22 纹理读回走 client-shadow 回退、3 query、1 inspection、1 FBO/RBO 删除后生命期 | P4b / P7 / P6 债 |
| `rsp` 残余输入;`SEG_REPLY` 2 MiB 单槽上限;GetCaps 两个 blobref 的载体;PACK-PBO 读回真实形式 | P3b/P4b、P6+ | | `rsp` 残余输入;`SEG_REPLY` 2 MiB 单槽上限;GetCaps 两个 blobref 的载体;PACK-PBO 读回真实形式 | P3b/P4b、P6+ |
| 15 个 class-C 槽(query / sync 尾 / `GetTexImage` / `SetSwapInterval` 等)无负载命中,仍具名拒绝 | P9 / P10 | | 15 个 class-C 槽(query / sync 尾 / `GetTexImage` / `SetSwapInterval` 等)无负载命中,仍具名拒绝 | P9 / P10 |
@@ -66,9 +67,10 @@
## 6. 下一步 ## 6. 下一步
1. **P6 spawn transport**`SocketTransport` + `ServerMain` + 握手 / 退出语义;替换 P5b 的三处 inproc 依赖(上表) 1. **P5c**c0c 契约 → tx(纹理 staged shadow/ ev`SEG_EVENT` producer/ hd(按句柄解析、caps 改读 server backend)并行 → ct`applier_reset` / `object_death` 记录)/ rv(值类残余值记录)→ gt(角色守卫门、`rsp` 按帧实测)。出口门 E-P5c 见 `ROADMAP.md`
2. 剩余首阻塞一轮(Magma compute/image、rd12、RGB mip、`texture-remint-pull` 仿真槽) 2. **P6 spawn transport**`SocketTransport` + `ServerMain` + 握手 / 退出语义 + EGL forwarder 的控制面帧;届时只换传输
3. P6 出口门:P5b 的完整渲染路径在 `spawn` 下绿;OpenRA 在 Adreno 830 上 split SSIM ≥ 0.99 3. 剩余首阻塞一轮(Magma compute/image、rd12、RGB mip、`texture-remint-pull` 仿真槽)
4. P6 出口门:P5b 的完整渲染路径在 `spawn` 下绿;OpenRA 在 Adreno 830 上 split SSIM ≥ 0.99。
## 7. 记录位置 ## 7. 记录位置
@@ -81,6 +83,7 @@
| P5b 合并普查 | `~/w7/p5b-final-census-348d22a4/`+ `-resume1/2/3`)、`p5b-results/joint-codex-v1.md` census 块 | | P5b 合并普查 | `~/w7/p5b-final-census-348d22a4/`+ `-resume1/2/3`)、`p5b-results/joint-codex-v1.md` census 块 |
| P5b 设备证据 | `~/w7/notes/p5b/apk/p5bcodex2/`APK + proof);`MobileGL/.trace-work/p5b-redmi/p5bcodex2/2f7cbe2e/`correctness 8/8、`ab-tables.md` 与 bsl 补充表) | | P5b 设备证据 | `~/w7/notes/p5b/apk/p5bcodex2/`APK + proof);`MobileGL/.trace-work/p5b-redmi/p5bcodex2/2f7cbe2e/`correctness 8/8、`ab-tables.md` 与 bsl 补充表) |
| class-C 普查 | `~/w7/notes/p6/census-classC.md`;基线 `~/w7/p5b-c0b-census-logs/results.json` | | class-C 普查 | `~/w7/notes/p6/census-classC.md`;基线 `~/w7/p5b-c0b-census-logs/results.json` |
| P5c 审计 | `~/w7/notes/p5c/p5c-audit-v1.md`59 行清单、wire-clean 清单、与契约的分歧、已有 `rsp` 数字)+ `BRIEF-p5c-audit.md`Kimi K3 只读静态审计,头 `a79a0af6`,关键行已由集成者逐条抽查 |
| 门日志 | `~/w7/p5-joint-gate.log``~/w7/p5b-quickgate.log``~/w7/p5-joint-evidence/` | | 门日志 | `~/w7/p5-joint-gate.log``~/w7/p5b-quickgate.log``~/w7/p5-joint-evidence/` |
| 脚本 | `~/w7/notes/tools/``wsl_p5_gate.sh``p5_ab_redmi.sh``p5b_codex_redmi.sh``wsl_build_p5_apks.sh``p6_census_*.{sh,py}``p5b-c0b-census.sh` | | 脚本 | `~/w7/notes/tools/``wsl_p5_gate.sh``p5_ab_redmi.sh``p5b_codex_redmi.sh``wsl_build_p5_apks.sh``p6_census_*.{sh,py}``p5b-c0b-census.sh` |
@@ -105,3 +108,4 @@
| 68 | class-C 普查决定迁移顺序(所有 Minecraft trace 首阻塞 = `DrawElements` → Minecraft 优先) | | 68 | class-C 普查决定迁移顺序(所有 Minecraft trace 首阻塞 = `DrawElements` → Minecraft 优先) |
| 76 | P5b 出口 = 主机门 `348d22a4` complete + 79 trace 普查 + Redmi 正确性 8/8 + 四臂 A/B | | 76 | P5b 出口 = 主机门 `348d22a4` complete + 79 trace 普查 + Redmi 正确性 8/8 + 四臂 A/B |
| 77 | Redmi 钉频期望 1050 → 1100 MHz2026-09-16);iris-bsl 8 组判为 fixture 123 帧上限,补充表不进 200 帧尾门表 | | 77 | Redmi 钉频期望 1050 → 1100 MHz2026-09-16);iris-bsl 8 组判为 fixture 123 帧上限,补充表不进 200 帧尾门表 |
| 78 | **P5c 插在 P6 之前**2026-09-17):`inproc` 先做到两角色之间除 wire 零直接内存访问,P6 只换传输;值类 BARRIER-PULLED 行在 P5c 过线,对象类行留 twin 表阶段;codex 无额度期间只读审计改派 Kimi(K3) |
+1 -1
View File
@@ -1,6 +1,6 @@
# MGPipeMobileGL 前后端拆分 # MGPipeMobileGL 前后端拆分
> 状态:**P0P5b 已收官**2026-09-16,代码头 `82683d4a`)。目标负载(四条 Minecraft A/B trace)已在 Redmi Adreno 830 上以 `inproc`(独立 apply 线程)双后端渲染,barrier tax 首次实测。**下一个是 P6 spawn transport**。当前头、逐门数字与开放项见 [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)。 > 状态:**P0P5b 已收官**2026-09-16,代码头 `82683d4a`)。目标负载(四条 Minecraft A/B trace)已在 Redmi Adreno 830 上以 `inproc`(独立 apply 线程)双后端渲染,barrier tax 首次实测。**下一个是 P5c**:审计(2026-09-17)显示 `inproc` 的两个角色仍有 59 处不经 wire 的直接内存访问(纹理纹素回读 client、反向通道裸指针、server 用 client 的 slot 分配器等),P5c 先把它们归零,**然后才是 P6 spawn transport**(计划见 `ROADMAP.md` "P5c 计划"。当前头、逐门数字与开放项见 [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)。
> >
> 性能纪律(2026-09-08 起):逐线程 CPU 与 tracker 绝对 ns **对着 pull 臂基线记录**,不作阻塞门;专门的优化阶段排在路线图推完之后。 > 性能纪律(2026-09-08 起):逐线程 CPU 与 tracker 绝对 ns **对着 pull 臂基线记录**,不作阻塞门;专门的优化阶段排在路线图推完之后。
+64 -3
View File
@@ -1,6 +1,6 @@
# MGPipe 路线图 # MGPipe 路线图
> 状态:**P0、P0.5、P1、P2、P3a、P4a、P5、P5b 已收官**2026-09-16,代码头 `82683d4a`)。当前头、逐门数字、开放项与下一步见 **[`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)**;设计见 `ARCHITECTURE.md`;逐阶段实测见 `MEASUREMENTS.md`。**下一个是 P6 spawn transport**。 > 状态:**P0、P0.5、P1、P2、P3a、P4a、P5、P5b 已收官**2026-09-16,代码头 `82683d4a`)。当前头、逐门数字、开放项与下一步见 **[`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)**;设计见 `ARCHITECTURE.md`;逐阶段实测见 `MEASUREMENTS.md`。**下一个是 P5c**`inproc` 的共享内存读点归零,2026-09-17 已审计、已计划、未开始,见下文"P5c 计划"),**然后才是 P6 spawn transport**。
## 通用纪律(每个 commit ## 通用纪律(每个 commit
@@ -12,7 +12,7 @@
- **拆分不借机顺手修 `dev` 的 bug**:句柄化过程中发现的 `dev` 侧缺陷记成独立条目、独立 PR(开放问题 15、17)。 - **拆分不借机顺手修 `dev` 的 bug**:句柄化过程中发现的 `dev` 侧缺陷记成独立条目、独立 PR(开放问题 15、17)。
- 过程(用户 2026-09-16,ID-66):不过度验证;轮次间不做对抗性审查,每个 P 阶段收官由 Codex 审一次,发现进入下一阶段首轮;只读 / 非核心任务派给 Codex;实现方与审查方错开模型族。 - 过程(用户 2026-09-16,ID-66):不过度验证;轮次间不做对抗性审查,每个 P 阶段收官由 Codex 审一次,发现进入下一阶段首轮;只读 / 非核心任务派给 Codex;实现方与审查方错开模型族。
两条跑道分开:**monolith 跑道** P0 → P0.5 → P1 → P2 → P3a → P4a → P3b/P4b → P7 → P8 → P13,每段可独立交付、可随时中止;**IPC 跑道** P5 → P5b → P6 → P9 → P10 → P11 → P12。目标顺序:先完整的 separate-thread renderingP5b,已达成),再 separate-process transportP6)。 两条跑道分开:**monolith 跑道** P0 → P0.5 → P1 → P2 → P3a → P4a → P3b/P4b → P7 → P8 → P13,每段可独立交付、可随时中止;**IPC 跑道** P5 → P5b → **P5c** P6 → P9 → P10 → P11 → P12。目标顺序:先完整的 separate-thread renderingP5b,已达成),再`inproc` 变成只经 wire 交换的诚实两角色(P5c),最后才是 separate-process transportP6,此时只是传输替换)。
## 阶段 ## 阶段
@@ -26,7 +26,8 @@
| **P4a** handle wave 2Espryt):FBO / 纹理 / sampler / program | ✅ `8c458cd5` | 十四条族调用接线(framebuffer state、sampler state / view、texture params、shader images、shader state、draw / dispatch program、global constants);纹理 / renderbuffer 复用 `resource_*`(目录不加行);六种 kind 按 `{slot, gen}` 重键;`CompositeResolver``Named = 3` framebuffer 记录;消费者门 + 客户端依赖表;位 9–12,push 默认 `0x1fff`emulation 在 split 下具名 Fatal | 全门:G1 0/0/0/0G5 17 区;G2 2902;单元 1785×3`integration-gpu` 1117 七臂;verify 920retrace 79/79;八族拒绝普查 0`PipeApplyPeek` 白盒对照。实际 1 天。§5 | | **P4a** handle wave 2Espryt):FBO / 纹理 / sampler / program | ✅ `8c458cd5` | 十四条族调用接线(framebuffer state、sampler state / view、texture params、shader images、shader state、draw / dispatch program、global constants);纹理 / renderbuffer 复用 `resource_*`(目录不加行);六种 kind 按 `{slot, gen}` 重键;`CompositeResolver``Named = 3` framebuffer 记录;消费者门 + 客户端依赖表;位 9–12,push 默认 `0x1fff`emulation 在 split 下具名 Fatal | 全门:G1 0/0/0/0G5 17 区;G2 2902;单元 1785×3`integration-gpu` 1117 七臂;verify 920retrace 79/79;八族拒绝普查 0`PipeApplyPeek` 白盒对照。实际 1 天。§5 |
| **P5** 传输 + inproc applier + 发射表 | ✅ `ff2994d9..37fc4fdb` | 同一 codec 上的 `InProcessTransport`;四种 build flavour;发射表三类 / caps mirror / reply mailboxapply-thread context 终身持有;lockstep verb barriertight ReadPixelspersistent-map 块推送;G8 字段归属生成器;split 测试 / CI / APK 车道;八包(c0 契约、w1 codec、s1 session、p1 归属、b1 persistent map、t1 车道、c1 路由、v1 server+ j0 / x2 / v1-r3 收尾 | jointOpenRA inproc 2/2 SSIM 1.0`integration-split` 21/21E1 14/14 红;G1 0/0/0/0。收尾头全门在 E3(a) 停止(设计性 skip 被判红),Part 2/4 未到达;收官审查 1 blocker / 10 major / 2 minor → P5b r1/r2。§6 | | **P5** 传输 + inproc applier + 发射表 | ✅ `ff2994d9..37fc4fdb` | 同一 codec 上的 `InProcessTransport`;四种 build flavour;发射表三类 / caps mirror / reply mailboxapply-thread context 终身持有;lockstep verb barriertight ReadPixelspersistent-map 块推送;G8 字段归属生成器;split 测试 / CI / APK 车道;八包(c0 契约、w1 codec、s1 session、p1 归属、b1 persistent map、t1 车道、c1 路由、v1 server+ j0 / x2 / v1-r3 收尾 | jointOpenRA inproc 2/2 SSIM 1.0`integration-split` 21/21E1 14/14 红;G1 0/0/0/0。收尾头全门在 E3(a) 停止(设计性 skip 被判红),Part 2/4 未到达;收官审查 1 blocker / 10 major / 2 minor → P5b r1/r2。§6 |
| **P5b** `inproc` verb migration | ✅ `37fc4fdb..82683d4a` | class-C 普查决定顺序;d1 19 / i1 7 / t2 6 / f1 11 槽迁移;sync 五槽;具名 blitGLES mip descriptorr1 / r2;收官审查三项修复。发射表 A=2 / B=54 / C=15 | 主机全门 `348d22a4` complete`integration-split` 107/107;合并普查零回退、79 trace 72/6/1**Redmi 正确性 8/8 + 四臂 A/B、barrier tax 首测**。§7 | | **P5b** `inproc` verb migration | ✅ `37fc4fdb..82683d4a` | class-C 普查决定顺序;d1 19 / i1 7 / t2 6 / f1 11 槽迁移;sync 五槽;具名 blitGLES mip descriptorr1 / r2;收官审查三项修复。发射表 A=2 / B=54 / C=15 | 主机全门 `348d22a4` complete`integration-split` 107/107;合并普查零回退、79 trace 72/6/1**Redmi 正确性 8/8 + 四臂 A/B、barrier tax 首测**。§7 |
| **P6** spawn transport | 下一个 | `SocketTransport`socketpair + fork/execveenvp 剔除 + 强制 monolith 双保险);`ServerMain``MOBILEGL_IPC_SERVER_PATH` + `dladdr` 兜底;有界重试握手;EOF 即时退出;device-lost latch;替换 P5b 的三处 inproc 依赖 | P5b 的完整渲染路径在 `spawn` 下绿;进程树只多一个子进程;`HeadlessGL` fork 预检无孤儿;OpenRA 在 Adreno 830 上 split SSIM ≥ 0.99 | | **P5c** `inproc` 共享内存读点归零 | **下一个**2026-09-17 已计划,未开始) | server 端纹理 staged shadow`SEG_EVENT` 的三个 producersink / twin 按记录里的句柄解析;`applier_reset` / `object_death` 控制记录;值类 BARRIER-PULLED 行改残余值记录;角色守卫门。详见下文"P5c 计划" | 角色守卫开启下 `integration-split` / 普查 / 79 trace 全绿且每层守卫能红;纹理 `0xDD` audit 红一次;`SEG_EVENT` 往返红一次;`rsp` 只剩对象类行且按帧测得;Redmi 四臂复测记录 | P5b |
| **P6** spawn transport | P5c 之后 | `SocketTransport`socketpair + fork/execveenvp 剔除 + 强制 monolith 双保险);`ServerMain``MOBILEGL_IPC_SERVER_PATH` + `dladdr` 兜底;有界重试握手;EOF 即时退出;device-lost latchEGL forwarder 的控制面帧;P5c 留下的 `s_synced` / `g_syncedRenderStateParameters` 按 context 世代重置 | P5b 的完整渲染路径在 `spawn` 下绿;进程树只多一个子进程;`HeadlessGL` fork 预检无孤儿;OpenRA 在 Adreno 830 上 split SSIM ≥ 0.99 |
| **P3b / P4b** 深化(Espryt) | 待排 | 按存储属主键控的发射游标与 view 索引重映射;`g_fboTextureSyncList``ResolvedTextureBindingMemo` / `SamplerPassMemo` / image sweep / program registry 重键;XFB scatter 搬到 client;删 fragColor 重推导 workaround 与 `g_broadcastMemo*`raw-depth-fetch sampler 原生化;回读 / pack stateP4a 记下的 R-3 / R-4 / R-5 / R-7 / R-10 / R-11`ProgramArtifacts.h` 的 NDK 尺寸钉 | 纹理 / program 场景;CTS `texture_*` / `shader_image_*` / `packed_pixels` 在 0.5 pp 内;每一个 Iris trace`TextureUploadShapeScenario` 升级成门 | | **P3b / P4b** 深化(Espryt) | 待排 | 按存储属主键控的发射游标与 view 索引重映射;`g_fboTextureSyncList``ResolvedTextureBindingMemo` / `SamplerPassMemo` / image sweep / program registry 重键;XFB scatter 搬到 client;删 fragColor 重推导 workaround 与 `g_broadcastMemo*`raw-depth-fetch sampler 原生化;回读 / pack stateP4a 记下的 R-3 / R-4 / R-5 / R-7 / R-10 / R-11`ProgramArtifacts.h` 的 NDK 尺寸钉 | 纹理 / program 场景;CTS `texture_*` / `shader_image_*` / `packed_pixels` 在 0.5 pp 内;每一个 Iris trace`TextureUploadShapeScenario` 升级成门 |
| **P7** DirectVulkanMagma)全量迁移 | 待排 | 其余 10 个子系统:`SetupDrawSnapshot` 探测字段塌成 dirty mask;占位纹理原生化;具名 UBO host payloadD-B8);内部 shader 烘焙;`VertexInputStateFactory` 内容寻址 CSO;D18 容器纪律保留 | 集成 + trace 在 Magma 的 push 与 split 下全绿;verify 零分歧;`nm -D libMobileGLServer.so \| grep glslang` 为空;CTS 0.5 pp 内。**再基线检查点:中点完成子系统 < 40% 立即重定基线** | | **P7** DirectVulkanMagma)全量迁移 | 待排 | 其余 10 个子系统:`SetupDrawSnapshot` 探测字段塌成 dirty mask;占位纹理原生化;具名 UBO host payloadD-B8);内部 shader 烘焙;`VertexInputStateFactory` 内容寻址 CSO;D18 容器纪律保留 | 集成 + trace 在 Magma 的 push 与 split 下全绿;verify 零分歧;`nm -D libMobileGLServer.so \| grep glslang` 为空;CTS 0.5 pp 内。**再基线检查点:中点完成子系统 < 40% 立即重定基线** |
| **P8** emulation 下放 + 索引宿主镜像 + 协议广度 | 待排 | `MG_Impl/Pipe/HostResolve.cpp`(client 数组范围、最大索引扫描、`*IndirectCount` 解析,逐站点 reconcile);`Server/IndexHostMirror`CopyImage 镜像搬到 clientviewport-array 回放验证;`generate_mipmap` 计划 + CPU 回退纹素;大 blob carrier(开放问题 11);无 present fence tick`kCapDriverOrderedXfbCapture` | `'^DirectGLES\.Split\.'``'^DirectGLES\.'` 逐名相同;trace split 双后端 SSIM ≥ 0.99 含两个 `coherent_as_flush` fixture`ClientArrayAfterComputeWriteScenario``create-indirect``roundtrips-per-frame` 读零;`index-mirror-bytes` 逐用例发布 | | **P8** emulation 下放 + 索引宿主镜像 + 协议广度 | 待排 | `MG_Impl/Pipe/HostResolve.cpp`(client 数组范围、最大索引扫描、`*IndirectCount` 解析,逐站点 reconcile);`Server/IndexHostMirror`CopyImage 镜像搬到 clientviewport-array 回放验证;`generate_mipmap` 计划 + CPU 回退纹素;大 blob carrier(开放问题 11);无 present fence tick`kCapDriverOrderedXfbCapture` | `'^DirectGLES\.Split\.'``'^DirectGLES\.'` 逐名相同;trace split 双后端 SSIM ≥ 0.99 含两个 `coherent_as_flush` fixture`ClientArrayAfterComputeWriteScenario``create-indirect``roundtrips-per-frame` 读零;`index-mirror-bytes` 逐用例发布 |
@@ -38,6 +39,66 @@
CTS 周转单独计价(`gl44to46` 约 56,271 例):逐阶段只跑该阶段可能影响的具名块;完整 caselist 只在架构边界与合并 `dev` 之前跑,放 CI 不放关键路径。 CTS 周转单独计价(`gl44to46` 约 56,271 例):逐阶段只跑该阶段可能影响的具名块;完整 caselist 只在架构边界与合并 `dev` 之前跑,放 CI 不放关键路径。
## P5c 计划:`inproc` 的共享内存读点归零(审计头 `a79a0af6`2026-09-17
**为什么插在 P6 之前**P5 / P5b 的 `inproc` 只把 verb 记录、`SEG_STAGE` blob、reply 与 caps 快照做成了 wire。对 `a79a0af6` 的只读静态审计(`~/w7/notes/p5c/p5c-audit-v1.md`,59 行清单,逐条在该头上重新解析)证明两个角色之间仍有一批**不经任何载体的直接内存读写**,靠 verb barrier 与同一地址空间才正确。它们不是传输问题:`spawn` 换掉的只是 ring 的传递方式,而这些读写在另一个进程里根本没有对应内存。P5c 的目标是让 `inproc` 诚实——两线程之间除 `SEG_CMD` / `SEG_STAGE` / `SEG_REPLY` / `SEG_EVENT` / caps 快照 / 控制帧之外零直接访问——从而 P6 只是传输替换。**本节只是计划,尚未实现。**
### 审计清单(按家族;`file:line` 以 `a79a0af6` 为准,完整 59 行见报告)
| # | 方向 | 直接访问的是什么 | 站点 | 今天为何能工作 | 现有守卫 | P5c 载体 |
|---|---|---|---|---|---|---|
| T1 | S→C 读 | **纹理纹素**`resource_subdata` 已把 level 字节放进 `SEG_STAGE`,但 `ApplyTextureUpload` 只做门与累积、把指针丢掉,Espryt 同步时从 client 的 `MipmapStorage` 重读纹素;纹理对象的形状与脏区也直接读前端对象 | 丢指针 `MobileGL/MG_Pipe/PipeApply.cpp:989-1008`;重读 `DirectGLES/Managers.cpp:7315``MapMipmapData`)、`:6940``:7129``:7198`;形状 `:7314``:7332``:6878-6880``DirectGLES/DirectGLES.cpp:8502-8507``:8528-8529`;脏区 `DirectGLES/Managers.cpp:7360``:7371` | barrier + 同地址空间 | **无**:整个纹理家族不在 `FieldOwnership.def``rsp` / `MOBILEGL_IPC_STRICT_ERRORS` / `MOBILEGL_IPC_AUDIT` 都看不见 | server 端纹理 staged shadowbuffer `StagedShadowStore` 的纹理半边);`SyncMipmapsToBackend` 改读它,形状与脏区读描述符 |
| T2 | S→C 读写 | client 的 slot 分配器 `MGPipeSlots()`mip / CopyTex / twin 创建时按前端 `GetLifetimeId()` 在 client 分配器里查找甚至铸造 | `DirectGLES/DirectGLES.cpp:8087``DirectGLES/SlotTables.h:392-400``HandleOf``FindByLifetimeId`);铸造 `DirectGLES/SlotTables.h:232``GetOrCreate`)、`:418``:428``DirectGLES/Managers.cpp:2708``:4293``:5627``DirectGLES/DirectGLES.cpp:6706``:8185``:8564``:8659` | barriermip 只 Find 不 mint | 无(`MOBILEGL_ASSERT` 在 INFO 构建失效) | 记录已带句柄(`MGPMipPlan::Res``MGPCopyFromFramebuffer::Dst``MGPBlit::ReadFbo/DrawFbo`)→ `GetOrCreate(MGPipeHandle)``DirectGLES/SlotTables.h:278` |
| T3 | S→C 读 | 具名 blitclient 临时改绑自己的 read / draw 绑定槽,server 经 `MGB_CTX` 读绑定槽 | client `MobileGL/MG_Remote/Client/EmitTables.cpp:741-786`server `DirectGLES/DirectGLES.cpp:7782-7785` | barrier + RAII 恢复 | `rsp``GetFramebufferBindingSlot` | 记录里的 `ReadFbo` / `DrawFbo`sink 侧按句柄解析(`MobileGL/MG_Remote/Server/PipeApplier.cpp:228-244` |
| T4 | S→C 读 | `CopyTexImage2D` / `CopyTexSubImage2D` 经纹理单元绑定槽取目的纹理 | `DirectGLES/DirectGLES.cpp:8561-8563``:8656-8658` | barrier | `rsp``GetTextureUnitObject` | 记录里的 `Dst` 句柄 |
| T5 | S→C 写 | Magma 生成 mip 直接写 client 的 level 存储(Espryt 的重推导臂没有 Magma 对应) | `DirectVulkan/Renderer/VulkanRenderer.cpp:1562-1590`(调用 `:11317` | barrier | 无 | 与 GLES 同形:只按描述符验证 |
| B1 | S→C 读 | `BufferObject::HasDefinedContent()`,每个 ensure 的 draw 都读 | `DirectGLES/Managers.cpp:3147-3148``EnsureBufferResourceForHandle``:3141-3146` 自述为债) | barrier | 无 | 描述符旁的 live-content 位,client 发布 |
| B2 | S→C 读 | `HandleOfBuffer` 每次 ensure 读前端 `GetLifetimeId()` | `DirectGLES/Managers.cpp:2705-2716` | barrier + memo | 无 | 记录里的句柄 |
| B3 | S→C 读 | 旧 buffer 臂(`MappedData()` / `IsMapped()` / `GetChangeSerial()`)在 split 构建里位 7 清零时可达,arm resolver 只打一行 `MGLOG_D` | `DirectGLES/Managers.cpp:2586-2620`;臂体 `:1012-1022``:1119-1121``:2944-2949``:3281-3327` | 同进程 | 无 | 有传输时具名拒绝(同 `Fatal{PipeLegacyMemosDisabled}` 的形状) |
| B4 | S→C 读写 | XFB`SharedPtr<BufferObject>` 跨整个 span 持有,结束时 `WritebackFromBackend`scatter 对 client shadow 读改写 | `DirectGLES/DirectGLES.cpp:950``:1060``:1077``:1081``:1172``:1185` | barrier | 无 | `OnBufferWriteback` / `OnXfbScatterReady` 事件——P9 的题材,P5c 只记账 |
| R1 | S→C 写 | 反向通道是 apply 线程直接调进 client 的 `MG_State``OnBufferWriteback` 把**裸指针**塞进 `MGPBlobRef.Offset`client 侧再转回指针;consumer 会拒绝任何真实段 | 生产 `DirectGLES/Managers.cpp:2339-2343``Ops_H_Readback`);消费 `MobileGL/MG_Impl/Pipe/ResourceTracker.h:553-572`(拒绝真实段 `:560-564` | 同地址空间 + barrier | 无 | `SEG_EVENT` `kEventBufferWriteback`consumer 已在(`MobileGL/MG_Remote/Client/ClientSession.cpp:176-267`),**全仓零 producer**`MobileGL/MG_Remote/Server/ServerSession.cpp:484-492` 无调用者) |
| R2 | S→C 写 | `OnGpuWritten` 直接调进 client trackerMagma 更是绕过回调直接 `MarkGpuWritten()` | Espryt `DirectGLES/Managers.cpp:2729-2752`,喂入 `DirectGLES/DirectGLES.cpp:568``:616``:2601`Magma `DirectVulkan/Renderer/UniformManager.cpp:1075``:1231``DirectVulkan/Renderer/VulkanRenderer.cpp:11618` | 同地址空间 | `MGLOG_E_ONCE` | `SEG_EVENT` `kEventGpuWritten`consumer `MobileGL/MG_Remote/Client/ClientSession.cpp:227-236` |
| R3 | S→C 写 | 默认 framebuffer 附件(`pDefaultFramebufferInfo`)由 server 在 surface 创建时写 | `DirectGLES/DirectGLES.cpp:11519-11620`Magma `DirectVulkan/Renderer/SwapchainObject.cpp:276-335` | barrier;罕见 | 无 | `SEG_EVENT` `kEventSurfaceChanged`consumer stub `MobileGL/MG_Remote/Client/ClientSession.cpp:242-253` |
| R4 | S→C 写 | sticky forward`RecordError` 写 client 错误队列;`InvalidateCompileEnv` 写 client 编译环境(在 stamped verb 之外静默 no-op | `MobileGL/MG_Impl/Pipe/PipeFill.cpp:1753-1756``:1764-1772` | barrier | `rsp`strict 下 Fatal | `RecordError``OnGlError` 事件(顺序保证是 P9 的);`InvalidateCompileEnv` 的活已由 R-12 caps 重发布完成(`MobileGL/MG_Remote/Client/CapsMirror.cpp:78-80`),删 forward |
| R5 | — | `MGPipeCallbacks` 十个回调只装了两个,且都是 apply 线程内联调用;`SEG_EVENT` 段已创建、映射、握手公告、每个 reply verb 后排空,但没有任何生产者 | 安装 `MobileGL/MG_Impl/Pipe/ResourceTracker.h:606-613`;段 `MobileGL/MG_Remote/Server/ServerSession.cpp:285-301`;排空 `MobileGL/MG_Remote/Client/ClientSession.cpp:836` | — | 溢出 latch 与 `eventDropped` 已建未用 | 本身就是载体 |
| C1 | S→C 读 | Magma 四处直接读 client 镜像 `pActiveBackendObject->GetDynamicParameters()`Espryt 已改走 server 自己的 backend);Espryt 的格式表回落臂在 server backend 为空时读 client 镜像 | `DirectVulkan/DirectVulkan.cpp:713-715``DirectVulkan/Renderer/VulkanRenderer.cpp:667-676``DirectVulkan/Renderer/VertexInputStateFactory.cpp:249-250``:502-503``DirectGLES/Utils.cpp:50` | 镜像值等于快照 | 无 | server 自己的 `Backend()->GetDynamicParameters()`;回落臂拒绝 |
| G1 | shared | `gPipeInputs`client 残余填充写、applier 写、server 的 36 行 BARRIER-PULLED 读 | `MobileGL/MG_Backend/MGPipe/PipeInputs.h:806`;填充 `MobileGL/MG_Impl/Pipe/PipeFill.cpp:2798`applier `MobileGL/MG_Pipe/PipeApply.cpp:1415-1560`stamp `MobileGL/MG_Backend/MGPipe/PipeInputs.cpp:103-132``rsp` `MobileGL/MG_Backend/MGPipe/PipeInputs.cpp:72` | **只靠 verb barrier** 保证单写者 | `rsp` + strict Fatal + poison | 值类行(`GetActiveTextureUnit``GetMaxTouchedTextureUnit``GetTouchedBufferBindingPointCount``GetCurrentVertexAttribute`、XFB 六项、三个世代)→ 每 verb 一条残余值记录或按 `Coverage.def` 由 server 自答;**对象类行**`GetBoundVertexArray``GetProgramForDraw/Dispatch``GetTextureUnitObject``GetImageTextureBinding``GetFramebufferBindingSlot``GetBufferBindingSlot/Point`、sticky `GetTextureObject` / `GetProgramObject`)返回前端对象指针、无法序列化,留 P3b/P4b/P7/P8 的 twin 表 |
| G2 | C→S 写 | GL 线程在 `FreshlyPrimed` 时整体 `MGPipeApplierReset()` server 的 `g_applier` | `MobileGL/MG_Impl/Pipe/PipeFill.cpp:2654-2656``MobileGL/MG_Pipe/PipeApply.cpp:1202-1299` | barrier 的后置条件(validate 时无在飞记录) | 无 | make-current 边上的 `applier_reset` 控制记录 |
| G3 | C→S 写 | 六种前端对象死亡:栈上结构体指针经 mailbox 送到 apply 线程(framebuffer 没有 wire delete opcode | `DirectGLES/Managers.cpp:206-228` | 阻塞 + 同地址空间 | 无 | `object_death` wire 记录 |
| G4 | C→S 控制 | 十二个 `Server*` EGL forwarder 经 one-slot mailbox 传**函数指针 + `void*` 栈局部** | `MobileGL/MG_Remote/Client/BackendObject_Remote.cpp:125-264``MobileGL/MG_Remote/Server/ServerLoop.cpp:543-598` | 阻塞 | `Fatal{ApplyThreadNotRunning}` | P6 的控制面帧(P5c 不做) |
| G5 | C→S 读 | `ServerLoop::OnApplyThread()` 每条 routed 记录读;bring-up 直接读 `loop.Backend()` / `MGPipeGetResourceOps()` | `MobileGL/MG_Remote/Client/WireTables.cpp:71``MobileGL/MG_Backend/Init.cpp:100``:145``:164-170``:247` | 同进程 | — | client 本地角色标志;caps 快照的 cap 位(P6 顺手) |
| G6 | shared | 前端地址 / lifetime-id 键控的 Espryt twin registry;持前端裸指针的 memo`ResolvedDrawBuffers::Entry::frontend`、三张 texture sync list);server 读 `pDefaultFramebufferInfo``g_rawDepthFetchSamplerState``ScopedDefaultUnpackState::s_synced` 从不按 context 世代重置 | `DirectGLES/Managers.h:309-377``:1185``DirectGLES/DirectGLES.cpp:61-62``:1958-1987``:2846``DirectGLES/Managers.cpp:5806-5812` | barrier / server 私有 | — | P3b/P4b 的 twin 表重键与 D-C1`s_synced` 按 context 世代重置归 P6 |
| A1 | — | barrier 的 client 半边断言从未接线:`InBarrierWait()` 零调用点,只有 `ApplyThreadIsInsideApplier` 在 emit 时检查 | `MobileGL/MG_Remote/Client/ClientSession.cpp:880``:748-753` | — | — | 接上,或删掉契约里的这句声明 |
已确认 wire-clean、不进 P5cbuffer 全家族(`Ops_H_*` 只拿句柄 + 记录 + `SEG_STAGE` 字节,`StagedShadowStore::Adopt` 复制,`Fatal{StageSnapshotTooNarrow}` 六处);`resource_respecify` 初始字节双向拒绝;persistent map 仿真档按块过 `SEG_STAGE``Fatal{RoleViolation}` 挡住 apply 线程;`CreateShaderState` 归档是一个 blobcaps 的格式表与 renderer 字符串走 `CapsSnapshot` 控制帧(`GetCaps` 记录本身已死,只是卫生项);tight ReadPixels`DrawVbo` 用户索引;fence 家族;`gMGPipeSegmentResolver``gBackendFunctionsTable` 的角色划分。
### 包与顺序
| 包 | 内容 | 关闭的行 |
|---|---|---|
| **c0c** 契约 | `MG_Remote/CONTRACT-P5C.md`:纹理 staged shadow 的所有权与覆盖规则;`SEG_EVENT` 记录与 blobref 约定(`Seg = kSegEvent`);sink / twin 按句柄解析的规则;`applier_reset` / `object_death` 记录;角色守卫的语义(有传输时 apply 线程触前端对象表面、GL 线程触 server 状态表面都是 `Fatal{RoleViolation}`);残余值记录的字段表;把纹理家族补进 `FieldOwnership.def` | — |
| **tx** 纹理 | `StagedTextureStore``ApplyTextureUpload` 采纳 `SEG_STAGE` 字节到 server 侧 level shadow`SyncMipmapsToBackend`、形状读、脏区改读描述符与 shadow;Magma mip 改按描述符;`MOBILEGL_IPC_AUDIT``0xDD` 覆盖纹理 | T1、T5(T2 的 mip 半边随之) |
| **ev** 反向通道 | `ServerSession::PublishEvents` 接三个 producerwriteback / gpu-written / surface-changed),consumer 的段臂改为解析 `kSegEvent`Magma `MarkGpuWritten` 改走回调;`RecordError` 进事件(顺序仍 P9);删 `InvalidateCompileEnv` forward;溢出策略沿用 `ARCHITECTURE.md` §11.7 | R1R5 |
| **hd** 句柄解析 | blit / mip / CopyTex / `HandleOfBuffer` 的 sink 与 twin 按记录里的句柄解析(`GetOrCreate(MGPipeHandle)`),server 不再触 `MGPipeSlots()``HasDefinedContent` 改读描述符的 live-content 位;Magma 四处 caps 读改 server backend`Utils.cpp` 回落臂拒绝 | T2、T3、T4、B1、B2、C1 |
| **ct** 控制记录 | `applier_reset``object_death` 两条 wire 记录(framebuffer 首次有 delete opcode);mailbox 只剩 EGL forwarder 给 P6 | G2、G3 |
| **rv** 残余值 | 值类 BARRIER-PULLED 行改为每 verb 的残余值记录(或 server 自答),`gen_pipe_field_ownership.py` 把它们改成 RECORD-SUPPLIED;对象类行保持 BARRIER-PULLED 并逐行标注归属阶段 | G1 的值类半边 |
| **gt** 门 | 角色守卫(两层 `Fatal{RoleViolation}`,仅 split 构建、有传输时生效);`InBarrierWait` 接线;旧 buffer 臂传输拒绝;`rsp` 按帧进 stats 行并在四条 A/B trace 上测得;CI 加一条 `MOBILEGL_IPC_STRICT_ERRORS=1` + 角色守卫的 `integration-split` 车道 | A1、B3,以及所有行的红一次证据 |
顺序:c0c → tx / ev / hd 并行 → ct / rv → gt 收口。每包自带 red-onceR-16),阶段末一次 Codex / Kimi 审查(ID-66)。
### 出口门(E-P5c
1. **角色守卫下全绿**:守卫开启时 `integration-split`107)、broad inproc 车道对 `348d22a4` 普查零回退、79 trace 无新增首阻塞;关掉任一层守卫必须能在一条具名用例上变红。
2. **纹理字节不再回读 client**`MOBILEGL_IPC_AUDIT=1` 对纹理 staged 字节的 `0xDD` 填充在四条 A/B trace 上无失败;把采纳改回丢指针必须变红。
3. **`SEG_EVENT` 有生产者**:三条事件的往返单元与集成用例;排空点上 `eventDropped == 0`;把 producer 改回裸指针必须变红。
4. **`rsp` 分类完成**:四条 A/B trace 每帧 `rsp` 已测;剩余读全部是对象类行,名单由 `FieldOwnershipTest` 钉住,值类行为 0。
5. **Redmi 四臂复测**(记录,不设门):writeback / gpu-written 改走事件后 barrier tax 重新记录。
6. G1 0/0/0/0、G2 / G14、G5 照旧。
### 留给后续阶段的(P5c 不碰)
对象类 BARRIER-PULLED 行与 twin registry 的前端键(P3b/P4b、P7);XFB scatter / `OnXfbScatterReady``OnTexturePullRequest` 与终止符、`OnGlError` 有序化(P9);EGL forwarder 的控制面(P6);`copy-image-shadow-mirror` 与 CopyTex 纹素回写(P8 / P9);`s_synced` / `g_syncedRenderStateParameters` 的 context 世代重置(P6)。
## 里程碑 ## 里程碑
- **P2 出口(2026-09-08):GO/NO-GO 判定继续**——五部分门全绿,逐线程 CPU 代价约 +10% 被接受;tracker 绝对 ns 上限降为记录项。 - **P2 出口(2026-09-08):GO/NO-GO 判定继续**——五部分门全绿,逐线程 CPU 代价约 +10% 被接受;tracker 绝对 ns 上限降为记录项。