docs: deliver isolated blind V13 audit STEP-096
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
tei
2026-09-25 21:31:27 +09:00
parent 82e8a18de7
commit b5c1c4879a
4 changed files with 353 additions and 0 deletions

View File

@@ -0,0 +1,231 @@
# STEP-096 V13 隔离盲审调查 v1
本报告仅使用 `/Users/tei/dev/MapLibreParticleV13Blind096` 内的当前规范、任务书与源码。发现由本轮独立阅读、追踪调用链及反例检查形成;未读取外部仓库、其他轮次审查、历史报告、会话日志、网页或既有审查结论。未构建、未执行测试、未运行设备、未修改源码。
## 1. 输入、结论边界与证据等级
- 合同:[STEP-096 任务书](../40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md)。已读取根 AGENTS、PARTICLE_BASELINE、项目规范目录、总则 README 指定的当前有效文件。
- 唯一目录:`/Users/tei/dev/MapLibreParticleV13Blind096`。目标导出 SHA:`ee0b89e711bf01335b3aa71d36def785cd97fec3`,来源为任务书声明;本轮没有 Git 对象可供独立核验,未运行 Git。branch、当前 HEAD、Git clean/remote 状态均为 NOT AVAILABLE。
- [release manifest](../../release/maplibre-particle/release-manifest.json#L4) 声明 particleRevision=13、sourceCommit=`ddf20dec9fe9cd05b77274827b6825829500dd5a`,RN/Android 为 `13.4.1-particle.13`,iOS 为 `6.28.0-particle.13`。manifest 的 sourceCommit 是产物来源声明,不能替代本次快照导出 SHA,也不能据此断言导出错误。
- 当前基线总则仍包含 `.3` 发布坐标;本轮以快照源码及 `.13` manifest 描述实现。此为文档口径差异,未据此推断线上产物错误。manifest 的发布成功字样不是本轮公网回读证据。
- 当前工作机器观察值为 `Mac-mini-tei.lan`;工作日期为 2026-09-25。实际 TUI 启动命令、screen 归属、模型配置及 reasoning 设置的独立启动记录均 NOT AVAILABLE;不访问目录外补证,不声称核实了 RDC 启动要求。
“确定缺陷”指限定触发条件下源码控制流或数值关系已闭合,不表示已复现用户事故。“源码确定成本”指可证明的调用、遍历、分配或等待,不表示 profiler 排序。“设计限制”指当前能力或上界不足。所有 GPU 画面、耗时、卡顿、OOM、崩溃、性能收益均 NEEDS_RUNTIME;所有构建和测试均 NOT RUN。未发现可由本轮证据成立的 P0。
## 2. 独立架构地图
| 路径 | 实际责任和所有权 | 审查定位 |
|---|---|---|
| RN RendererRuntime → 平台 bridge → Map/Renderer → RenderOrchestrator → segment plan | Host 提交策略配置;Style 层顺序仍是绘制顺序来源,策略在该顺序上划分区间 | [RN 入口](../../packages/maplibre-particle-rn/src/RendererRuntime.ts#L22)、[分段计划](../../src/mbgl/renderer/render_segment_plan.hpp)、[Renderer](../../src/mbgl/renderer/renderer_impl.cpp#L583) |
| Renderer → RetainedUnderlayCache → gfx RenderPass/OffscreenTexture → GL/Metal | Renderer 持有各 retained 段缓存;缓存拥有离屏纹理/合成资源;同帧 PaintParameters 穿过多个目标 | [缓存生命周期](../../src/mbgl/renderer/retained_underlay_cache.cpp#L201)、[渲染调度](../../src/mbgl/renderer/renderer_impl.cpp#L798) |
| RN FieldRuntime → Android/iOS bridge → WeatherRuntime/MLNParticleFieldRuntime → RasterArraySource | bridge 定位地图并派发;Source 持有 encoded store、绑定、forecast clock;发布不可变 Impl/投影供 RenderLayer 读取 | [RN API](../../packages/maplibre-particle-rn/src/FieldRuntime.ts)、[Source 提交](../../src/mbgl/style/sources/raster_array_source.cpp#L422) |
| encoded ingress → QBIN V2/V3 → profile validator → EncodedFieldStore/FieldSeries → binding/window | magic 分派格式,校验结构和 profile;每个 fieldKey 保存时间序列;时间窗选取后物化数组 | [V3 解码](../../src/mbgl/particle/ingress/qbin_v3_decoder.cpp)、[profile](../../src/mbgl/particle/field/field_profile_validator.cpp)、[series](../../src/mbgl/particle/field/field_runtime.cpp#L144) |
| projection → WeatherColorLayer / RasterParticleLayer → GL/Metal shader | 色场与粒子分层;颜色消费标量或向量幅值;粒子持有场纹理、State A/B、Trail A/B 和 drawable/tweaker | [物化](../../src/mbgl/particle/field/field_projection_materialization.cpp#L201)、[粒子更新](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1489)、[颜色更新](../../src/mbgl/renderer/layers/render_weather_color_layer.cpp#L205) |
正常路径存在实际保护:Style diff 处理增删/重排;无效分段与不支持场景可 fallback;稳定 retained 帧可复用;解码有结构、尺寸、CRC 等检查;同时间身份冲突和陈旧修订会拒绝;超出时间覆盖范围不会凭空外推。Source 使用共享不可变帧/投影,使读者可持有旧快照;粒子 tweaker 使用 weak_ptr,不能仅因资源与 drawable 互相引用的表象断言泄漏。
固定边界的实现情况:正式 Host 提交路径未要求 Native 承担 provider/manifest 下载;旧 fixture/local FileSource 路径应单独理解。RN 是控制入口,绘制仍在 Native Core。粒子模块有独立 field/ingress/render 层,但 Renderer/RenderOrchestrator 中也存在较多集成逻辑;没有上游对照输入,无法量化“薄接入”变更比例。Wave/Tide/Current 的共享地理掩码要求见 B09。GL 与 Metal 不能由共享 C++ 自动推出行为一致;Vulkan 完整粒子链未在本轮闭合。
## 3. 独立发现总表
编号按本轮源码证实顺序,排除的候选不占编号;优先级是建议处理顺序,不是实测事故等级。
| 编号 | 优先级 | 类型 | 置信度 | 发现及作用边界 |
|---|---|---|---|---|
| B01 | P1 | 确定缺陷 | 高 | 切换离屏/主目标未重置 tile stencil 的 CPU 覆盖记录 |
| B02 | P1 | 确定缺陷 | 高 | Metal RenderPass 没有落实 gfx 的 clearDepth/clearStencil 请求 |
| B03 | P2 | 源码确定成本 | 高 | Metal 每次离屏 present 显式等待 GPU 完成 |
| B04 | P2 | 源码确定成本 | 高 | retained 内容失效同时释放同尺寸 GPU 资源 |
| B05 | P2 | 源码确定成本 | 高 | 时间更新先全量物化场,再判断投影是否相同 |
| B06 | P1 | 确定缺陷 | 高 | encoded PLAY 无生产路径推进 forecast clock |
| B07 | P2 | 确定缺陷 | 高 | 8-bit 对称场编码不能表示零,产生有符号偏差 |
| B08 | P2 | 确定缺陷 | 高 | Mercator 东向 U 位移缺少纬度修正因子 |
| B09 | P2 | 设计限制 | 高 | 当前掩码为合成 fixture,未形成共享地理 Ocean Mask |
| B10 | P2 | 源码确定成本 | 高 | 平台 UI 派发链同步解码并物化 encoded 数据 |
| B11 | P2 | 设计限制 | 高 | encoded store 仅限制每序列帧数,无全局字节/key 上界 |
| B12 | P2 | 确定缺陷 | 高 | retained 段绘制抛异常后仍可能标记缓存构建成功 |
| B13 | P1 | 确定缺陷 | 高 | 粒子场更新门槛漏掉合法时间窗内的 V/有效性变化 |
### B01 — stencil 覆盖记录没有随渲染目标切换
**触发与调用链。** 多个 retained 段,或 retained 构建后主目标绘制,复用相同瓦片集合且需要 stencil 裁剪。[Renderer buildRetainedRange](../../src/mbgl/renderer/renderer_impl.cpp#L798) 共用 PaintParameters;[beginBuild](../../src/mbgl/renderer/retained_underlay_cache.cpp#L304) 创建清 stencil=0 的离屏 pass,GL 只更新 stencil 可用性;随后[主 pass](../../src/mbgl/renderer/renderer_impl.cpp#L839) 也清 stencil=0。[updateStencilBufferAvailability](../../src/mbgl/renderer/paint_parameters.cpp#L100) 不清覆盖表;[tileIDsCovered](../../src/mbgl/renderer/paint_parameters.cpp#L147) 和[早退](../../src/mbgl/renderer/paint_parameters.cpp#L185) 只看 tile ID,不看 attachment。下一目标仍会用[旧的 Equal stencil ID](../../src/mbgl/renderer/paint_parameters.cpp#L365)。[GL LayerGroup](../../src/mbgl/gl/layer_group_gl.cpp#L67) 正常调用掩码生成,也无法绕过这个早退。
**所有权、正常/错误/销毁。** 覆盖表属于同帧 PaintParameters,stencil 内容属于每个目标附件。下一帧重建 PaintParameters 不能修复同帧跨目标;[显式 clearStencil](../../src/mbgl/renderer/paint_parameters.cpp#L156) 会重置记录,但上述目标切换没有调用。资源创建失败有 fallback,与本问题不同;正常创建成功即可触发。在 GL 已清为 0 的新目标上,旧正 ID 与实际内容不一致的路径已证实。Metal 的清屏另受 B02 影响。
**反例与边界。** 同一 attachment 内复用覆盖记录是正确优化;瓦片集合改变可能重绘掩码;无裁剪图层、没有跨目标构建或全部退回主绘制的帧不满足条件。不能据此称所有 retained 帧都缺图,实际画面 NEEDS_RUNTIME。
**安全修复/最小验证。** 在目标/attachment 世代切换时失效掩码元数据及 ID 分配状态,保留同目标复用;不可在已绘制内容中途随意清 stencil。构造 R/C/R 和 R/R 共用瓦片的 fill/line 层,逐目标检查掩码写入及截图,与关闭 retained 对照;含稳定复用、相机变化、主目标后续 live 层。
### B02 — Metal 没有传递 depth/stencil 清屏语义
**触发与证据。** retained beginBuild 明确请求 depth=1、stencil=0;[Metal offscreen bind](../../src/mbgl/mtl/offscreen_texture.cpp#L62) 新建 descriptor 并挂接 color/depth/stencil 纹理。[Metal RenderPass 构造](../../src/mbgl/mtl/render_pass.cpp#L13) 只处理 clearColor,没有读取 clearDepth 或 clearStencil;[GL 对应构造](../../src/mbgl/gl/render_pass.cpp#L14) 把这些请求交给 clear。调用链为 Renderer → cache.beginBuild → gfx descriptor → Metal RenderPass → MTL descriptor,丢失发生在最后的转换。
**所有权与反例。** 附件属于 offscreen texture,pass/command encoder 管理本次命令。创建和销毁附件均不等于每次按请求清屏。主平台 descriptor 可自行配置清屏,不能证明新建离屏 descriptor 已正确配置;无 depth/stencil 的 pass 不受这两个字段影响。未使用外部 SDK 默认值推断确定黑屏,也未把未显式设置 StoreAction 直接定性为丢帧。模拟器 stencil attachment 分支另需设备验证。
**影响/修复/验证。** 确定的是 gfx 请求未落实,裁剪/深度表现 NEEDS_RUNTIME。统一转换各附件的 clear/load/store 语义,分别覆盖有无 clear 值、有无附件及模拟器组合格式。用非默认 depth/stencil clear 值做离屏后续比较测试,并核对 GPU capture;不得以 color 正常替代 depth/stencil 验证。
### B03 — Metal 离屏 present 中存在同步等待
**触发与链。** [RenderTarget::render](../../src/mbgl/renderer/render_target.cpp#L71) 在每个 target 绘制结束后 present;[Metal command encoder](../../src/mbgl/mtl/command_encoder.cpp#L29) 调 resource.swap;[OffscreenTexture::swap](../../src/mbgl/mtl/offscreen_texture.cpp#L86) commit 后执行 waitUntilCompleted,再重置命令缓冲。粒子稳态在[目标注册](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L2097) 中至少包含 StateWrite 和 TrailWrite,初始化还有额外读目标;retained 构建也有 present。
**所有权、边界和反例。** 等待保护命令/资源完成,是确定同步点,不是已测出的长时间阻塞。仅实际执行这些目标的帧计入;停绘、未激活层不计,retained 稳定复用不计新的 cache build 等待,GL 不经过此 Metal 函数。完成/销毁安全不能通过简单删 wait 保证。
**修复/最小验证。** 研究同队列命令依赖与完成回调持有资源,合并或延后提交,保留读写顺序及销毁保护。Metal capture 记录单粒子层每帧 command buffer、wait 次数和 CPU 等待时长,再测多粒子层、首帧、retained 重建及移除层;性能收益 NEEDS_RUNTIME。
### B04 — 内容失效与资源释放绑定
**触发与链。** 相机矩阵/内容 revision 改变而 viewport 尺寸不变。[Renderer revision 更新](../../src/mbgl/renderer/renderer_impl.cpp#L583) → [cache evaluate](../../src/mbgl/renderer/retained_underlay_cache.cpp#L201) → releaseResources → [prepareResources](../../src/mbgl/renderer/retained_underlay_cache.cpp#L244) 重新创建离屏资源。[releaseResources](../../src/mbgl/renderer/retained_underlay_cache.cpp#L365) 清掉纹理、合成组及资源键。
**正常/错误/销毁与反例。** 缓存对象持有资源,失效已实际释放所有权;稳定 valid 分支会 Reuse,不能称每帧都分配。viewport、格式、context 改变或最终销毁确需释放;资源创建异常已有 fallback。本 finding 针对同尺寸、同 context 的内容失效成本,不主张旧图继续有效。
**修复/验证。** 分开“内容有效性”和“附件可复用性”,保留匹配资源键的附件并重绘。固定 viewport 平移/缩放,对比 offscreen 创建次数、峰值显存、帧时间;再覆盖 resize/context 重建,防止错误跨 context 复用。成本路径已证实,分配耗时与收益 NEEDS_RUNTIME。
### B05 — 时间更新重复物化整个场
**触发与链。** Host 高频 setEncodedForecastTime,包括相同非零时间。[setRequestedForecastTime](../../src/mbgl/style/sources/raster_array_source.cpp#L453) → refreshV4RendererState;[clock setter](../../src/mbgl/particle/field/field_runtime.cpp#L196) 不因同值返回 false;[refresh](../../src/mbgl/style/sources/raster_array_source.cpp#L496) 先物化两类投影,再用 sameProjection 比较。[validity](../../src/mbgl/particle/field/field_projection_materialization.cpp#L69) 展开 bitset,[vectorSnapshot](../../src/mbgl/particle/field/field_projection_materialization.cpp#L105) 遍历向量;颜色 UV 与粒子各有自己的 T0/T1 物化。[sameProjection](../../src/mbgl/style/sources/raster_array_source.cpp#L65) 还会比较实际数组。
**所有权和反例。** 新数组在临时共享快照中,比较相同后可释放;发布新 Impl 时旧读者继续持有旧快照。无投影、无绑定、无法解出窗口会少做或跳过相关分支。相同内容可避免发布或 GPU 重传,故不等于每次都上传纹理;每个动画帧也不一定调用该时间 setter。完整性校验是必要成本,问题是同内容重复重建。
**成本/修复/验证。** N 个格点、两个时间面、颜色 UV 与粒子同时激活时,四份 vector+valid 基础数组约为 36N 字节的新逻辑存储,另有比较/校验遍历和旧快照重叠。缓存以完整不可变内容身份(含两分量、validity、grid、解释规则)为键,将 mix/time 与数组物化分离。统计同值时间、仅 mix 变化、跨窗、修订替换时的分配与上传次数;不得牺牲 B13 所需的完整身份。
### B06 — encoded PLAY 没有接入 forecast clock 推进
**触发与链。** 提交两帧、绑定、设置时间后,经公开 API 切 PLAY 并等待 repaint。[Source 播放设置及 advanceForecastClock](../../src/mbgl/style/sources/raster_array_source.cpp#L459) 中,播放设置只改 clock 状态,推进由独立方法完成。对 src/include/platform/RN 生产路径检索 advanceForecastClock 仅有[声明](../../include/mbgl/style/sources/raster_array_source.hpp#L240)和定义,没有调用方。Android [repaint timer](../../platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/WeatherRuntime.java#L225) 与 iOS [timer](../../platform/ios/src/MLNParticleFieldRuntime.mm#L147) 只触发重绘;粒子[读取 v4 mix/cadence](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1262) 不推进该 clock。
**正常/错误/销毁与反例。** clock 由 Source 所有;平台 timer 的生命周期清理不提供时间增量。[advance 实现](../../src/mbgl/particle/field/field_runtime.cpp#L209) 本身存在且处理溢出;[测试](../../test/source/raster_array_v4_host_api.test.cpp#L297) 直接手动调用,所以不能证明公开 PLAY 可自行推进。Host 持续设置 forecast time、C++ 调用方自行 advance、旧 sourceTimeline 路径均是反例;粒子在固定场中移动也不代表预报时刻在播放。
**修复/验证。** 为 encoded clock 指定唯一推进所有者和单调时钟来源,处理暂停/恢复、rate、地图移除、颜色单层及多层,避免每层重复推进。仅调用一次 setTime 和 PLAY,观察 requestedForecastTime/mix 随 elapsed 改变;暂停保持、恢复不跳跃、不同 rate 成比例,窗口末端行为明确。公开路径缺口可静态确定,运行表现 NEEDS_RUNTIME。
### B07 — 零值在 8-bit 场纹理中变成负值
**触发与证据。** 有效向量为零或接近抵消。[粒子编码](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L174) 用 uint8 转换 `(x / scale * 0.5 + 0.5) * 255`,scale 至少为 1;[颜色编码](../../src/mbgl/renderer/layers/render_weather_color_layer.cpp#L45) 同类处理;[GL 解码](../../shaders/particle_gpu_validation.fragment.glsl#L76) 还原为 `(channel * 2 - 1) * scale`,Metal [解码](../../include/mbgl/shaders/mtl/particle_gpu_validation.hpp#L48) 同理。x=0 被截为 127,解码为 `-scale/255`,两个零分量都带偏差,最小 scale=1 时向量长度也高于 1e-5 的近零阈值。
**边界和反例。** 场快照的 CPU float 正确不代表上传表示正确;无效点被 valid 分支拒绝,不计入这个有效零场问题。不同数值/缩放下误差相对大小不同;方向归一化可放大近零偏差。理论截断误差小于 `2*scale/255`,这是假定合法编码区间的算术界,不是 GPU 实测。重用或销毁纹理不会改变表示误差。
**修复/验证。** 选取可精确表达零的带符号编码或 float/half 表示,并评估纹理兼容性;仅改四舍五入仍无法让奇数 255 的对称映射精确表示零。以有效零场、微小速度、正负对消、纯东/北场做 GPU 解码读回和粒子位移检查,GL/Metal 同测。实际漂移像素/速度 NEEDS_RUNTIME。
### B08 — Mercator 东向位移少一个 sec(latitude)
**触发与链。** formal profile 使用 eastward/northward、m/s 的 U/V 语义,见[profile 校验](../../src/mbgl/particle/field/field_profile_validator.cpp#L25)。上传缩放在 shader 中还原后,[GL formal 位移](../../shaders/particle_gpu_validation.fragment.glsl#L169) 取 `dx=U*dt/C`、`dy=-V*dt/(C*cos(latitude))`;[Metal](../../include/mbgl/shaders/mtl/particle_gpu_validation.hpp#L133) 同样处理。这里 C 为地球周长,输入链未见对 U 预乘 sec(latitude)。
**推导、反例和边界。** Mercator x=λ/(2π)+0.5,而局部东向速度满足 dλ/dt=U/(R*cosφ),故 dx 应为 U*dt/(C*cosφ)。赤道、U=0 时不受此项影响;60° 纬度当前东向投影位移为应有值的一半。统一 visual time scale 不修复东西/南北相对畸变。此为固定输入语义下的数学缺陷,实际视觉速度、极区处理 NEEDS_RUNTIME;与资源销毁和错误 fallback 无关。
**修复/验证。** 在一致纬度与极区夹紧策略下对两个分量使用正确度量转换,保留既定视觉时间倍率。0°/45°/60° 的等物理速度东西向和南北向场,比较 CPU 解析预测与单步 GPU 位移;含符号、反向、极区边界与跨日期变更线。
### B09 — Ocean Mask 尚未形成正式共享地理输入
**触发与证据。** Wave/Tide/Current 需要 OCEAN_ONLY,或启用当前 mask 模式。[makeCoastalMaskFixture](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L281) 用格点坐标表达式生成合成海岸,formal 资源初始化[仍安装该 fixture](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1314)。物化[统一写 GLOBAL](../../src/mbgl/particle/field/field_projection_materialization.cpp#L77)。[顶点 shader](../../shaders/particle_gpu_validation.vertex.glsl#L56) 的 v_world 源自 quad 坐标,粒子合成[据此采样 mask](../../shaders/particle_gpu_validation.fragment.glsl#L262);[颜色分支](../../shaders/particle_gpu_validation.fragment.glsl#L113) 在该处理前返回。
**所有权、正常路径与反例。** mask 纹理由粒子资源拥有,随资源重建/销毁;缺少正式地理 mask 数据入口和两类层共享采样语义。默认关闭 mask 的 GLOBAL wind 不因此错误,Host 数据 nodata 也可能已有陆地缺测,但这不等价于独立共享 Land/Ocean Mask。不能把本限制扩展为所有风场不可用。
**修复/验证。** 由 Host 决定业务域策略,Core 接收明确地理坐标、网格和版本的共享掩码,两层统一采样;不把 provider/下载引入 Native。加载真实小型固定海岸 mask,平移、缩放、旋转后地理边界应固定;分别验证 Wind GLOBAL 与 Wave/Current OCEAN_ONLY,以及 nodata 叠加、删除与替换。当前设计缺口已证实,设备画面 NEEDS_RUNTIME。
### B10 — encoded 提交在 UI 派发链同步完成重工作
**触发与链。** RN 提交较大 QBIN。[Android bridge](../../packages/maplibre-particle-rn/android/src/main/java/org/navsea/maplibre/particle/weather/WeatherRuntimeBridgeModule.kt#L310) 经 runOnUiQueueThread 定位并调用 runtime;[Java submit](../../platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/WeatherRuntime.java#L97) → [JNI](../../platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp#L1501) 拷贝 bytes 并同步调用 Source。iOS [withMapForTag](../../packages/maplibre-particle-rn/ios/WeatherRuntimeBridge.mm#L105) 使用 UI block → [runtime submit](../../platform/ios/src/MLNParticleFieldRuntime.mm#L222) 拷贝并解码。V3 [CRC](../../src/mbgl/particle/ingress/qbin_v3_decoder.cpp#L66) 对字节做位循环,后续解码/校验/投影也在同步调用链内。
**边界、错误与反例。** Android 本地文件读取在 UI 派发之前,不能笼统写成全部文件 IO 都在 UI;小文件和 Duplicate 后的工作量不同,格式失败会提前返回。解码有大小上限,但允许的输入仍可较大。临时 bytes、decoded frame、Source 持久状态的所有权清楚;问题是所在线程及连续占用,并非已证明泄漏。未观测 ANR 或卡顿。
**修复/验证。** worker 只做不可变 bytes 解码/校验,带 map/style/source 世代令牌返回所有者线程提交;限制队列并处理取消、地图销毁和过时结果,不能把整个可变 Source 移到 worker。在中小/近上限输入、CRC 失败、连发及页面退出下记录 UI 区间耗时、峰值内存和错误回调。性能影响 NEEDS_RUNTIME。
### B11 — 每序列八帧不是全局内存预算
**触发与链。** 单 Source 连续提交不同有效 fieldKey。[EncodedFieldStore 成员](../../include/mbgl/particle/field/field_runtime.hpp#L151) 是 map 和 perSeriesCapacity=8;[submit](../../src/mbgl/particle/field/field_runtime.cpp#L223) 可为新 key 创建 series;[FieldSeries](../../src/mbgl/particle/field/field_runtime.cpp#L168) 只检查本序列容量。Source [提交](../../src/mbgl/style/sources/raster_array_source.cpp#L422) 不要求该 key 已绑定。V3 [输入上限](../../src/mbgl/particle/ingress/qbin_v3_decoder.cpp#L19) 限单帧 encoded/decoded bytes,不限 store 总量。
**所有权和反例。** store 持有共享帧,直到显式 clear/clearAll 或 Source 销毁;渲染读者可能延长旧快照寿命。单帧 decoded 上限 32 MiB 与八帧组合形成每序列最高 256 MiB 的逻辑上界,但不表示每个 profile 都能达到该值。key 数无总上界,不能据此保证 Source 总内存。Host 固定少量 key 并主动清理时可控;本轮没有 OOM 证据。
**修复/验证。** 在提交前计入全局 key/字节预算,包含共享去重与临时峰值;明确容量拒绝语义,保护当前绑定窗口,避免静默淘汰。循环提交多个合法 key,验证达到预算后稳定拒绝且现有窗口可用;clear 后可恢复,地图销毁后所有者释放,读者完成后最终释放。设计上界不足已证实,实际内存峰值 NEEDS_RUNTIME。
### B12 — 构建过程错误没有阻止 retained 缓存成功提交
**触发与链。** retained 范围内某 LayerGroup 在 render 时抛出被捕获的异常,observer 记录错误后正常返回。[RenderOrchestrator 遍历](../../src/mbgl/renderer/render_orchestrator.hpp#L156) 捕获异常并 onRenderError,不把失败状态返回调用方。[buildRetainedRange](../../src/mbgl/renderer/renderer_impl.cpp#L798) 在 opaque/translucent 遍历后继续 finishBuild、markBuildSucceeded;[成功标记](../../src/mbgl/renderer/retained_underlay_cache.cpp#L328) 使其可在后续稳定帧 Reuse。
**所有权、错误/销毁与反例。** 缓存持有可能只完成部分绘制的纹理,直到下次失效或销毁。资源准备阶段[有 catch/fallback](../../src/mbgl/renderer/retained_underlay_cache.cpp#L240),不属于本路径;无异常、observer 再抛出异常、随后 revision 立刻改变都不满足持续复用条件。此处只讨论同步可捕获 render 异常,不将异步 GPU 错误视作同一证据。
**修复/验证。** 让范围绘制返回成败或设置本次构建错误标记,失败不提交 valid 缓存,安全 fallback/下帧重试;保留 observer 通知,不引入每帧 GPU 等待作为错误检测。用一次性抛异常的假 LayerGroup 和正常返回的 observer,检查 BuildFailed、禁止 Reuse、下一帧成功恢复,再由 GL/Metal 场景验证画面。
### B13 — 粒子更新身份没有覆盖第二分量和有效性
**触发与可构造输入。** 同 fieldKey 的三个不同 validTime 帧使用相同 fieldID/generation/dataVersion,U 内容相同、V 依次变化(或 validity 变化),网格和 schema 兼容。此输入在[FieldSeries 新时间插入](../../src/mbgl/particle/field/field_runtime.cpp#L146) 合法:newerRevision 检查针对同一 timestamp,未要求不同时间递增 generation。窗口从 T0/T1 切到 T1/T2。
**完整调用链。** [materializeParticleProjection](../../src/mbgl/particle/field/field_projection_materialization.cpp#L201) 仅以 t0/t1FirstPlane 身份传给 baseSnapshot;[baseSnapshot](../../src/mbgl/particle/field/field_projection_materialization.cpp#L77) 用 fieldID+该身份组成 fieldID,保留 producer generation/dataVersion。[Source sameProjection](../../src/mbgl/style/sources/raster_array_source.cpp#L65) 比较实际数组,可正确发布新的 V/validity。但[粒子 sourceChanged](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1489) 只调用[fieldIdentityChanged](../../include/mbgl/particle/field/field_data_adapter.hpp#L111),其只比 generation/fieldID/dataVersion。两个槽身份都未变时,不进入内部 sameFieldGpuContent/纹理更新分支,继续使用旧场纹理。
**所有权、反例和边界。** Source 新投影存在、Renderer 仍持有旧 resources.field/nextField 及纹理,直到其他身份变化、重建或销毁。每时次主动递增 generation、U 也变化、初次资源创建都能触发更新;纯 mix 变化且窗口内容确实不变应保留纹理。此 finding 不指向颜色层:颜色投影的实际内容比较是反例,已排除“颜色仅看 U 而漏掉 V”的候选。
**修复/最小验证。** 粒子更新门槛使用包含 U/V、validity、grid 与解释语义的完整不可变内容身份;窗口时间状态单独更新,保持相同内容可复用。采用上述三帧并让 V/validity 可见地不同,seek 跨窗,检查 CPU 选窗、GPU 上传/复用判定及读回;增加不同时间同 generation、仅 V 改变、仅有效性改变、完全相同内容四组。错误门槛可静态证明,旧场画面 NEEDS_RUNTIME。
## 4. 反例检查及未成案候选
- **颜色投影身份:排除。** Source sameProjection → sameSnapshot → sameFieldGpuContent 会比较两分量/validity 实际数组;不能仅因第一 plane 参与 fieldID 就断言颜色不更新。B13 另有粒子特定的前置门槛证据。
- **粒子资源强引用环:排除。** [ValidationDrawableTweaker](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L770) 持 weak_ptr;[layerRemoved](../../src/mbgl/renderer/layers/render_particle_validation_layer.cpp#L1140) 移除目标。本轮未形成泄漏闭环。
- **关闭缓存后辅助段状态残留:排除简单结论。** [synchronizeRetainedUnderlayState](../../src/mbgl/renderer/renderer_impl.cpp#L142) 覆盖段缓存同步;不能仅查主缓存 setter。
- **纯重排未被处理:排除。** [Style diff](../../src/mbgl/renderer/style_diff.cpp#L19) 与[orchestrator 更新](../../src/mbgl/renderer/render_orchestrator.cpp#L318) 处理移除/添加并重建有序层;分段不是独立 Z-order 数据源。
- **任意交错不受支持:排除笼统结论。** 单 continuous 段的 fast path 限制不等于普通 segmented path 不支持多段;[普通绘制](../../src/mbgl/renderer/renderer_impl.cpp#L938) 仍按计划遍历。透明混合、深度与遮挡整体等价性尚需运行验证。
- **异常输入必然越界:未成案。** QBIN 有 MaxCells、字节预算、偏移/结构/CRC 检查,FieldSeries 有冲突/陈旧/兼容性拒绝。未完成形式化证明或 fuzz,不能声称完全安全,也未凭大输入符号制造越界 finding。
## 5. 性能与资源模型(静态模型,非 benchmark)
设视口为 W×H,retained 段数 K,格点数 N,活跃粒子层数 L,每层有效粒子数 P,encoded 字节数 E,fieldKey 数 F。
| 路径 | 静态成本模型 | 稳定路径/限制 |
|---|---|---|
| retained | 每段至少一张 RGBA8 颜色纹理约 4WH 字节,另加实际 depth/stencil 附件、对齐及 drawable;总量随 K 线性增长 | 稳定内容复用;Build 时绘制该段并合成;B04 增加同尺寸分配抖动 |
| 粒子 | State A/B 随状态纹理面积增长,Trail A/B 随视口面积增长;积分和粒子绘制约随 P 增长,全屏衰减/合成随 WH 增长 | 初始化/重播种还有额外工作;不可只凭 particleCount 推断全部成本 |
| Metal 提交 | 实际执行的粒子层稳态至少两次离屏同步点/层,加当帧 retained Build 数量及其他 target | 这是显式 wait 次数下界模型,不是每次都发生长等待;需 capture 核对实际启用分支 |
| 时间 setter | 激活投影物化和数组相等比较为 O(N),颜色 UV+粒子约 36N 字节基础新数组 | 单纯 draw 并不必然调用 setter;不同 scalar/vector 绑定成本不同 |
| QBIN | CRC 和解码大体随 E/样本数增长;提交链还会临时复制并可能物化 | 上限约束单帧;失败可以提前结束,不可套用最坏值到所有输入 |
| encoded store | 每 key 最多八帧,但总量随 F 增长;另有 materialized snapshot、上传图像、在途旧读者 | 需要显式 clear;现有容量拒绝保护单序列,未构成全局预算 |
未取得 profiler、锁竞争、allocator、GPU capture 或设备温度数据。不提供热点排名、FPS、毫秒、节省比例或确定 OOM 阈值。查到同步等待和 UI 同步调用,不等于证明死锁;本轮未形成有闭环证据的锁死 finding。
## 6. 测试源码覆盖与缺口
阅读测试源码只表示理解其断言,以下全部 NOT RUN。
| 已阅读的代表性测试 | 能说明的设计意图 | 不能替代的验证 |
|---|---|---|
| [retained 状态测试](../../test/renderer/retained_underlay_cache.test.cpp#L116)、[失败测试](../../test/renderer/retained_underlay_cache.test.cpp#L479)、[segment 测试](../../test/renderer/retained_underlay_cache.test.cpp#L657) | Build/Reuse/Fallback、范围与交错计划 | 真实 attachment stencil、Metal 清屏、异常经 orchestrator 传递、透明/深度像素等价 |
| [clock 测试](../../test/particle/field_runtime.test.cpp#L272)、[Host API clock](../../test/source/raster_array_v4_host_api.test.cpp#L297) | 手动 advance 的时间算法 | 平台 PLAY 是否接入生产推进者 |
| [materialization 测试](../../test/source/raster_array_v4_host_api.test.cpp#L392)、[颜色幅值](../../test/source/raster_array_v4_host_api.test.cpp#L433) | 快照不变性、mix、重建计算 | GPU 8-bit 数值误差、B13 跨窗同 producer 身份、数组分配次数 |
| [binding 测试](../../test/particle/field_binding.test.cpp#L84)、[V3 解码测试](../../test/particle/qbin_v3_decoder.test.cpp#L346) | 内容身份/选面、格式失败和边界 | 全 renderer 资源切换、UI 延迟、全局 key 预算及竞态销毁 |
未覆盖或未闭合:Vulkan/WebGPU 完整粒子实现、所有 Style 图层组合、真实设备 Metal simulator/device 差异、GPU 厂商驱动行为、平台业务调用频率、RN 安装/codegen/ABI、所有 error string 和 promise 回调分支、跨线程竞争注入、完整 fuzz、产物字节与 manifest 的对应关系。当前审查是有边界的静态追踪,不是逐行穷尽全仓或安全证明。
## 7. 后续可执行验证矩阵(交给 RDC,全部 NOT RUN)
本轮禁止执行以下构建/测试。RDC 在独立获准的验证阶段准备测试 runner 与设备;新增回归用例/修复属于后续代码任务,不能把下表当作本轮已提供可运行补丁。
| 项目 | 准备与执行动作 | 最小通过条件 |
|---|---|---|
| B01 | GL、Metal 各加载同瓦片 fill/line,策略 R/C/R、R/R、C/R/C;首帧/重建/复用逐帧对照关闭缓存 | attachment 切换均生成对应掩码,像素裁剪等价 |
| B02 | 离屏附件预置非默认值,创建带 depth/stencil clear 的 pass,再以比较绘制检查;device/simulator 各一次 | clear 值与请求一致,无依赖未定义旧内容 |
| B03/B04 | 1/2 粒子层、1/3 retained 段;固定视口平移 300 帧,记录 capture/分配/CPU 等待 | 给出次数、时长分布;资源复用变化有证据且无画面回归 |
| B05 | 两时间面,固定时间重复 100 次、mix 小步变化 100 次,再跨窗和修订 | 输出物化/分配/上传次数;相同内容复用且变化可靠可见 |
| B06 | 仅颜色、仅粒子、两者共存;setTime 一次后 PLAY、PAUSE、不同 rate | forecast time/mix 正确推进,每地图只推进一次 |
| B07 | 有效零场、微值、正负对消、东西南北常量场,GPU 单步读回 | 零保持零,近零阈值一致,误差有明确预算 |
| B08 | 0°/45°/60°,相同 m/s、相同 dt,比较解析 Mercator 位移 | U/V 投影度量一致,符号正确,极区有限值 |
| B09 | 同一固定地理 mask 同时供颜色/粒子,平移缩放旋转,切 GLOBAL/OCEAN_ONLY | 两层海陆边界一致且固定在地理位置 |
| B10 | 合法中小/近上限 QBIN、坏 CRC、连发、加载中移除地图 | UI 耗时可量化;回调一次;无过时提交/释放后访问 |
| B11 | 多 key 连续提交直至预算,clear 后再提交 | 可预测拒绝、峰值有界、当前窗口不破坏、最终释放 |
| B12 | 假 LayerGroup 首次抛异常,observer 记录后返回,下一帧正常 | 首次不得缓存成功;下一帧重试并恢复 |
| B13 | 同 generation/dataVersion/U 的三时次,分别仅改 V、validity,再 seek 跨窗 | 新窗口 GPU 内容正确;完全相同内容仍可复用 |
| 兼容 | 增删/重排/隐藏边界层,透明层交错、3D/custom fallback、resize/context 重建 | Style 顺序一致,fallback 可恢复,无残留目标 |
已有 C++ 定向测试的执行入口需使用平台生成的实际 runner;[test/CMakeLists](../../test/CMakeLists.txt#L1) 的 mbgl-test 是库,[macOS 配置](../../platform/macos/macos.cmake#L84) 定义 mbgl-test-runner。RDC 已构建并确认路径后可执行下列命令(本轮未执行;路径必须由 RDC 填写):
```sh
RDC_TEST_RUNNER=/absolute/path/to/mbgl-test-runner
"$RDC_TEST_RUNNER" --gtest_filter='Retained*:ContinuousLayerRange.*:RenderSegment*:ParticleFastPath.*:ParticleField*:ParticleQbin*:ParticleEncoded*:Source.RasterArrayV4*'
```
这只运行现有匹配测试,不覆盖全部上述新增场景。RDC 应先确认 runner 的过滤输出确实命中测试,保存命令、exit code、测试数量和日志路径;设备场景记录设备/后端/版本、输入 fixture、截图或 capture。实际构建目录、签名、设备 ID、安装产物及历史日志均 NOT AVAILABLE,本轮不臆造构建命令或成功状态。
## 8. 分批建议与停止边界
1. **先补正确性闭环:** B01/B02 的目标附件状态、B06 的唯一时钟推进者、B13 的完整内容身份;加入最小回归后再做跨后端运行验证。B12 同批修复失败提交语义,避免错误缓存长期复用。
2. **再统一数值与域语义:** B07/B08 的数值表示/投影度量,以及 B09 的共享地理掩码;用解析输入和小型固定 fixture 定量验收。
3. **最后按测量做性能与预算:** B03/B04/B05/B10/B11,先记录同步、分配、线程耗时和峰值,再分别改命令提交、资源复用、物化缓存、工作线程和容量策略;避免多项同时修改而无法归因。
本轮仅交付三份中文盲审文档,不修改实现或测试。完成后停止,由 RDC 冻结三份原稿 SHA-256 和时间,再独立移交、追加开发记录并做正式仓库 scoped 提交及远端核验。本会话不参与解除盲态比较,不根据外部材料回写发现。
配套:[Step 记录](../50_Step记录/STEP-096_V13隔离盲审_v1.md) · [完成报告](../报告/STEP-096_V13隔离盲审_Codex完成报告_v1.md)

View File

@@ -0,0 +1,56 @@
# STEP-096 V13 隔离盲审 v1
## 状态与范围
状态:**完成(仅隔离盲审文档交付)**。日期:2026-09-25。
本阶段按[当前任务书](../40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md)独立读取隔离快照源码和当前规范,形成调查、Step 与完成报告。完成不表示 V13 构建、测试、GPU 画面或性能通过。未做代码修复,后续验证全部 NOT RUN。
## 输入与可核实环境
| 项目 | 事实及限制 |
|---|---|
| 唯一工作目录 | `/Users/tei/dev/MapLibreParticleV13Blind096` |
| 机器观察值 | `Mac-mini-tei.lan` |
| 目标导出 SHA | `ee0b89e711bf01335b3aa71d36def785cd97fec3`,来自任务书;未用 Git 对象独立核验 |
| 版本声明 | [manifest](../../release/maplibre-particle/release-manifest.json#L4):revision 13,RN/Android `13.4.1-particle.13`,iOS `6.28.0-particle.13` |
| 产物 sourceCommit 声明 | `ddf20dec9fe9cd05b77274827b6825829500dd5a`,不作为本快照 HEAD |
| 当前 branch / Git HEAD / clean / remote | NOT AVAILABLE;本轮未运行 Git |
| 实际 TUI、screen、模型和 effort 启动记录 | NOT AVAILABLE;未访问目录外配置、会话日志或终端回放补证 |
已读取 AGENTS.md、PARTICLE_BASELINE.md、`docs/00_项目规范/`、总则 README 及所列当前有效总则,包括当前基线与开发路线 v2,以及本任务。当前总则中的旧发布坐标与快照 `.13` 声明分开记录,不重写总则或历史。未打开外部路径、历史调查/Step/完成报告、既有审查材料或开发日志;本轮输出目录只用于写入和检查本轮三份新稿。
## 只读过程
1. 从公开 API 和目录建立 Style/分段、Renderer/gfx、场 ingress/runtime、平台 bridge 与 GPU 数据路径地图。
2. 追踪正常、拒绝、fallback、失效和销毁路径,区分 owner、共享不可变快照与 GPU 资源;对候选寻找反例,不按问题数量补齐。
3. 阅读 C++、GLSL、Metal、Android、iOS、RN、测试源码和配置;核对公开 PLAY 调用方、纹理更新条件、attachment 状态、CRC/容量、线程派发与同步点。
4. 排除颜色投影仅看第一分量、强引用环、关闭缓存同步遗漏、纯重排遗漏等未成立候选;保留粒子独立前置更新门槛的完整证据。
5. 写入三份中文报告;对本轮新稿进行文件存在、相对链接、引用行号和行尾空格的轻量静态检查。未启动构建、测试 runner、设备或 profiler。
## 结果
调查形成 **13 条独立 finding**:P1 四条(B01、B02、B06、B13),P2 九条;无 P0。类型为确定缺陷七条、源码确定成本四条、设计限制两条。这里的“确定”限定源码控制流/数值语义,不代表已发生用户事故;全部运行效果 NEEDS_RUNTIME。
主要正确性证据为跨渲染目标 stencil 记录、Metal depth/stencil clear 请求传递、encoded 播放推进、粒子完整内容身份、8-bit 零值和 Mercator 度量、retained 失败提交。成本和设计限制涉及 Metal 同步等待、资源重复分配、重复物化、UI 同步处理、共享地理 mask 与 store 总预算。每条的条件、精确路径/行号、反例、影响边界、安全修复与验证方案见调查报告。
## 三份交付文件
| 文件 | 内容 |
|---|---|
| [调查报告](../20_调查/STEP-096_V13隔离盲审调查_v1.md) | 架构地图、B01—B13 证据、反例、性能模型、覆盖缺口、验证矩阵、分批建议 |
| [本 Step 记录](STEP-096_V13隔离盲审_v1.md) | 范围、输入、只读过程、结果、未运行验证、后续责任 |
| [Codex 完成报告](../报告/STEP-096_V13隔离盲审_Codex完成报告_v1.md) | 交付状态、发现索引、证据质量、边界与移交方案 |
## 未运行验证与阻塞
- CMake/Ninja/Xcode/Gradle、编译、链接、codegen、打包:**NOT RUN**。
- C++/GL/Metal/Jest 测试、设备安装/启动、GPU capture、性能与内存测量:**NOT RUN**。
- Git 状态、commit、push、远端核对和产物公网回读:**NOT RUN**。
- 外部仓库、上游差异、真实安装环境、历史日志、启动配置:**NOT AVAILABLE**。
这些是任务约束和证据边界,不阻塞文档交付;它们阻止把本报告升级为运行态或发布验收。未确认 Vulkan 全链、全部图层组合及竞态行为,详见调查覆盖缺口。源码未写入;没有 Git diff 或导出对象逐文件比对证据,不声称已核验工作树 clean。
## 下一步与停止
Codex 在三份报告自检后停止,不继续修复、追加开发日志或解盲比较。RDC 随后冻结三份原稿的 SHA-256 与时间,独立移交正式仓库同路径、追加 `粒子开发记录.md`,执行四文件 scoped commit/push 和远端核查;这些动作本轮均未执行。新代码任务优先处理 B01/B02/B06/B13,并补 B12 失败恢复;其余数值/域语义和性能/容量工作按调查报告分批推进。验证场景和已有 runner 的定向执行命令已写入调查报告,交由后续 RDC 阶段执行。

View File

@@ -0,0 +1,55 @@
# STEP-096 V13 隔离盲审 Codex 完成报告 v1
执行结果:**PASS(仅盲审文档交付)**。日期:2026-09-25。
本轮只使用隔离快照及其当前有效规范和[任务书](../40_任务/STEP-096_V13隔离盲审_Codex任务_v1.md),独立读取源码形成结论,未导入任何既有审查发现。PASS 不表示 V13 Android/iOS GPU 运行态、性能、构建或发布通过。
## 交付
1. [独立调查报告](../20_调查/STEP-096_V13隔离盲审调查_v1.md):架构、完整发现证据、反例、成本模型、覆盖缺口、后续验证矩阵及分批建议。
2. [Step 记录](../50_Step记录/STEP-096_V13隔离盲审_v1.md):输入、只读过程、范围、结果和未运行事项。
3. [本完成报告](STEP-096_V13隔离盲审_Codex完成报告_v1.md):交付结果、索引、证据边界与移交责任。
三份正文与相对链接、引用文件及行号、行尾空格已作轻量静态自检;这不属于构建或测试执行。
## Finding 索引
完整路径、行号、触发条件、反例和验证动作集中在调查报告对应 B 编号中。编号来自本轮源码证实顺序。
| 编号 | 优先级 / 类型 | 独立发现 |
|---|---|---|
| B01 | P1 / 确定缺陷 | 跨目标 tile stencil 覆盖记录未失效 |
| B02 | P1 / 确定缺陷 | Metal 未落实 gfx depth/stencil 清屏请求 |
| B03 | P2 / 源码确定成本 | Metal 离屏 present 同步等待 GPU |
| B04 | P2 / 源码确定成本 | retained 内容失效释放同尺寸 GPU 资源 |
| B05 | P2 / 源码确定成本 | 时间更新先全量物化后比较 |
| B06 | P1 / 确定缺陷 | encoded PLAY 无生产时钟推进调用方 |
| B07 | P2 / 确定缺陷 | 8-bit 场纹理零值编码偏差 |
| B08 | P2 / 确定缺陷 | Mercator 东向速度未作纬度修正 |
| B09 | P2 / 设计限制 | 缺正式共享地理 Ocean Mask |
| B10 | P2 / 源码确定成本 | UI 派发链同步解码/物化 |
| B11 | P2 / 设计限制 | store 无全局 key/字节预算 |
| B12 | P2 / 确定缺陷 | retained 绘制异常后仍可提交成功缓存 |
| B13 | P1 / 确定缺陷 | 粒子更新门槛遗漏合法窗口 V/有效性变化 |
共 13 条,P1 四条、P2 九条,无证据成立的 P0。源码确定缺陷七条、确定成本四条、设计限制两条。颜色投影候选因实际数组比较而排除,粒子强引用环、纯重排遗漏等候选也未成案;没有为凑数量将其写成问题。
## 证据质量和输入限制
- 每条保留隔离树内真实源码定位及可构造条件,区分源代码事实与运行后果。同步点、分配/遍历、缺失调用方、身份门槛、数值公式可静态分析;设备画面、CPU/GPU 时长、OOM、崩溃和收益全部 **NEEDS_RUNTIME**。
- 目标 SHA `ee0b89e711bf01335b3aa71d36def785cd97fec3` 为任务书中的导出来源;隔离树不提供 Git 对象核验。本轮未运行 Git,未声称 branch、HEAD、commit、push、remote 或 clean。
- 快照 manifest 声明 RN/Android `13.4.1-particle.13`、iOS `6.28.0-particle.13` 和产物 sourceCommit `ddf20dec9fe9cd05b77274827b6825829500dd5a`;未外部回读,不能当作安装环境或产物字节核验证据。
- 实际模型/TUI/screen/effort 启动记录、历史构建日志、主仓库内容和其他审查材料均 **NOT AVAILABLE**;未向目录外寻找。当前规范中旧坐标仅作为设计/流程背景,不覆盖快照实现事实。
- 这是选择性静态追踪,未穷尽所有源码、后端和竞态。测试源码被阅读,不等于通过测试。Vulkan 全链、ABI/codegen、透明/深度全组合、平台销毁竞态和设备表现仍待后续验证。
## 验证与改动边界
构建、链接、codegen、打包、C++/GL/Metal/Jest 测试、设备安装/运行、profiler 和 GPU capture:**NOT RUN**。发布、公网回读、正式仓库操作和 Git:**NOT RUN**。
本轮只写任务规定的三份中文 Markdown 报告;未改生产源码、测试、shader、manifest、package/lock 或工具链,未追加开发日志。这里的“源码未变”指本轮没有源码写操作,不代表已借助 Git diff 或导出对象对比核验整个快照。
## 停止与移交
Codex 文档交付后停止。RDC 负责随后核对隔离输出清单、计算三份原稿 SHA-256 并记录冻结时间,再独立移交正式仓库、追加开发记录、做四文件 scoped commit/push 及远端核对。本轮没有执行散列冻结或移交,没有最终提交 SHA。
冻结后不由本会话依据外部资料改写发现。后续修复、测试和解盲比较应有独立任务与记录;所需最小验证矩阵已在调查报告给出。

View File

@@ -931,3 +931,14 @@ Android V3-08 单次综合验收已完成并关闭。Native `13.4.1-particle.2`
- F01~F10:6项CONFIRMED、4项QUALIFIED;新增stencil跨target、Metal附件/clear、失败cache发布、V4 PLAY无推进、JSON/数值入库/listener问题,以及物化/UI/普通粒子wait等遗漏成本。具体触发、反例、行号和建议批次见调查。 - F01~F10:6项CONFIRMED、4项QUALIFIED;新增stencil跨target、Metal附件/clear、失败cache发布、V4 PLAY无推进、JSON/数值入库/listener问题,以及物化/UI/普通粒子wait等遗漏成本。具体触发、反例、行号和建议批次见调查。
- 仅文档变更;无源码修复,无构建、测试、codegen、安装、设备或profiler。历史PASS仅HISTORY,运行影响NOT RUN/NEEDS_RUNTIME;不判V13产品验收通过。 - 仅文档变更;无源码修复,无构建、测试、codegen、安装、设备或profiler。历史PASS仅HISTORY,运行影响NOT RUN/NEEDS_RUNTIME;不判V13产品验收通过。
- 下一步由RDC独立复核证据与Git,优先验证stencil/Metal失败路径及PLAY,再按批次授权修复和验证。提交与推送事实见STEP-095阶段记录收尾。 - 下一步由RDC独立复核证据与Git,优先验证stencil/Metal失败路径及PLAY,再按批次授权修复和验证。提交与推送事实见STEP-095阶段记录收尾。
### 2026-09-25 STEP-096 V13 独立隔离盲审
- 从冻结源码 `ee0b89e711bf01335b3aa71d36def785cd97fec3` 导出无 `.git` 的独立源码快照,去除既有调查、任务历史、阶段记录、完成报告和开发日志,仅提供当前规范、源码与本轮任务书;全新 `gpt-6-astra high` 会话只读审查。
- 盲审正文先完成并冻结,独立 B01~B13 共13条(P1四条、P2九条);各项证据、反例和运行验证矩阵见三份 STEP-096 文档;没有进行其他审查结果的交叉比对。
- 冻结于 `2026-09-25T21:30:00.294786+09:00`,RDC 已校验隔离目录没有 Git metadata,启动后仅三份报告发生写入;三份原文 SHA-256:
- `docs/20_调查/STEP-096_V13隔离盲审调查_v1.md`:`b957a790310bc110c7135b512f39d5c82d5b6b0417c02abcd0e6743368551c18`(231行)。
- `docs/50_Step记录/STEP-096_V13隔离盲审_v1.md`:`c80535126dc08ef2f6f2c446d7186d96db64a58a9d43df64bd6f3ae248c05303`(56行)。
- `docs/报告/STEP-096_V13隔离盲审_Codex完成报告_v1.md`:`b0ff277c71db36c273579446aa974aebd4beb7635770810b1fe62d98b979ef9f`(55行)。
- 三份原稿字节等同复制至正式仓库;未修改生产源码、shader、测试、构建、manifest或依赖;本轮 Native/GL/Metal、Android/iOS实机及性能测试均 NOT RUN,产品运行态未验收。
- 当前轮次仅交付盲审与证据冻结;后续比较、修复和运行验证应另行授权。