12 KiB
STEP-110 R0 Placement 跨段归因与缓存安全边界只读调查 — Codex 任务 v1
一、任务性质与核心问题
性质:Particle Native / Shared Core 专项,只读调查;不实现、不修复、不编译、不上机。
用户要求粒子项目独立回答:
Native 能否区分“R0 自己的 Placement 变化”和“其他 RenderSegment 引起的 Placement 变化”?如果能区分,是否足以在不破坏 Symbol 碰撞、文字/图标位置及图层顺序的条件下让未变化的 R0 复用缓存?
必须把以下不同概念分开审查:
- 事件来源:哪个 source/layer/segment 引发了 placement/repaint/revision;
- 实际影响范围:全局碰撞计算是否使 R0 的 Symbol 位置、可见性、fade 或绘制结果改变;
- 缓存安全判据:能否证明 R0 内容/Placement 仍与已缓存画面等价;
- 当前实现:上述信息目前是否已有、是否按 Segment 使用、还是仅采用全局保守 Gate。
禁止预设“全局 Placement 变化一定是 Bug”,也禁止以“R0 自己没有提交数据”直接推导“R0 视觉必然没有变化”。
二、仓库、版本与事实优先级
- 项目:
/Users/tei/dev/MapLibreParticleLab,正式分支particle/main、远端origin/particle/main。 - 创建任务时只读确认:
particle/mainHEAD2df504cdc0403bdad85d3f31f16fd54a8744abac、干净工作树。执行时必须重新读取 Git 实际状态,不得把此 HEAD 当作永恒基线。 - NavSea 产品实机所用 APK 内
assets/component-manifest.json记录:RN / Android Native AAR13.6.1-particle.23。V23 正式来源对应refs/tags/maplibre-particle/rn/13.6.1-particle.23、GSRL Git commit87f3d1c59a52581fb8339f0ea7d106b9f4b94fef。 - 必须分别标明 V23 发布源码与当前
particle/main的事实。如当前 main 有未发行后续改动,不能以 main 代替 V23,不能以 V23 APK 推断未发行修复已经生效。 - 跨项目事实遵循
D:\React\navsea-particle-integration\instructions\NAVSEA_PROJECT_INSTRUCTIONS.md及最新 COORD / RFC / ADR / Contract / Status;当前既有外部契约 C-001。此任务不新增/更改公共 API 或契约。 - 粒子项目根
AGENTS.md、PARTICLE_BASELINE.md、docs/00_项目规范/、docs/00_项目总则/README.md与四份有效总则必须先读,按当前项目事实处理过时的历史环境/发布坐标。 - 必读既有证据:STEP-088、089、090、092、094、099、100、102、106、108、109;重点对比 STEP-090 早期缓存/快路成功条件、STEP-102 placement-free 分段隔离范围、STEP-106 T1/T2 Symbol 与 Annotation 边界的真实验收。
三、来自 NavSea 的问题证据(仅作为输入,不由本任务修改 NavSea)
FZG1-2 / Android 13 / V23 当前 APK,NavSea 采用两段 R-C:
- R0:RETAINED,31 层,
background至place-labels-land-ja,包含有 Placement 能力的 Symbol; - C1:CONTINUOUS,82 层,
rn-weather-color至chartDangerScanCenterLineLayer,包含天气/粒子和其他业务层。
固定同一风场、同一 map 生命周期,连续约 15.24 秒,mapReactTag=864、generation=4、configRevision=1、topologyRevision=8、113 层均不变:
- 风场期间进程 CPU 样本均值约 98.6% / 99.1%,关闭天气后约 4%~8%;
fastPathHit Δ0、fastPathMiss Δ452、fullCpuFrame Δ453;- R0
build Δ0、reuse Δ0、invalidation Δ453、fallbackCount Δ453、texture/composite createΔ0; - 两端
valid=true、fallback=false、sourceReady=true、sourceStable=true、placementChanged=true、placementGatePassed=false、cache.supported=false、cacheState=fallback、lastInvalidationReason=static-placement; mainBufferExecutionMode=mixed、globalLiveFallbackReason=none、fastPathFallbackReason=cache-invalid。
这些是症状,不代表已证明 C1 导致 R0 Placement 改变。 此外,历史较早的 V23 短时快照曾观察到 placementChanged=false 但 R0 记录仍为 static-placement,需要区分“当前门槛值”和“上次失效原因/诊断时序”,避免误读。
Mac 粒子团队如无法访问 Windows 原始快照,可依据上述冻结事实做 Native 只读审计;缺失证据须列为“需要后续验证”,不得自行编造 NavSea 图层或运行结果。
四、必须回答的调查问题
Q1:Placement 的产生与传播
从真实 V23 Native 代码绘制完整的因果链:
- 触发 RenderTree / Placement 计算的入口与时机是什么?
placementChanged、symbolFadeChange、placementTransitionActive、crossSourceCollisions分别表示当前帧/上帧/全局/局部的什么事实?何时清零或稳定?- Source/Layer 的 layout、tile、visibility、camera、animation 等变化,分别可能影响哪些 Placement 状态?
- R0 以外的 C1 Symbol/Annotation/业务层变化,在哪些条件下可能影响 R0 的符号碰撞与最终视觉?
- 如果 RenderTree 每次都重新算 Placement 但画面没有变化,如何区分“执行过计算”和“R0 最终结果发生变化”?
Q2:现有 R0 Gate 的作用域
调查 V23 实际调用链及数据结构,至少解释:
- R0 结构性
placementCapable如何判定,与动态needsPlacement()有何区别; - R0
placementGatePassed如何使用全局placementChanged、fade、transition; - R0
cache.supported、static-placement、actualExecution=live的完整因果关系; - R0 的 source-local mutation、segment fingerprint、retained revision 与 placement gate 是否真正各自独立;
- STEP-102 对 placement-free R 的隔离已解决什么、placement-bearing R 仍未解决什么;
lastInvalidationReason与当前失败条件是否可能属于不同采样/缓存生命周期。
Q3:能否证明“R0 不受 C1 变化影响”
针对以下反事实场景逐项作出有证据的判断:
- R0 含静态地名,C1 只有普通非 Symbol 动画/颜色/粒子更新;
- R0 含静态地名,C1 的 Symbol 内容变化,但不同 Source 且跨源碰撞关闭;
- R0 含静态地名,C1 的 Symbol 内容变化且跨源碰撞开启;
- R0 Symbol 自身 layout/tile/visibility/zoom 发生变化;
- Camera/pan/zoom/rotation/pitch 变化;
- Symbol Fade/Placement Transition 活跃或刚结束;
- C1 有内部自动插入的 Annotation Symbol(参照 STEP-106)。
每行必须分别给出:
- “谁触发 Placement”能否识别;
- “R0 最终 Placement/可见性是否改变”能否独立证明;
- 允许 R0 Reuse 的必要安全条件;
- 当前 V23 是否具备这种判定能力及证据来源;
- 无法证明时为什么必须继续 fail-closed。
严禁把“不同 Segment”简单等同于“碰撞和 Placement 相互独立”。
Q4:对 Fast Path 的影响(仅限前置依赖)
解释“R0 缓存有效”是否为 Fast Path 的必要条件但非充分条件。只读标出 R0 Gate 与单 C / unsupported continuous layer / revision / pending changes 等后续 Gate 的先后关系。不要扩大成 C1 全图层性能调查,不实施多 C 优化。
五、只读检查范围与方法
允许读取:
- 当前 Particle Core 的 Renderer、RenderOrchestrator、PlacementController、RenderTree、Symbol/Collision、Retained Cache、RenderSegment Plan、Diagnostics 与 Fast Path 相关源码;
- V23 tag 与当前
particle/main的只读git show、git diff、git log; - STEP-090/102/106 等历史设计、报告、设备验证结果;
- 现有 C++ 定向测试源码与 Validation 场景源码(只读,不执行、不修改)。
建议从当前实际路径 src/mln/renderer/ 与相关 Shared Core 源码定位,不得沿用旧 STEP 中过时的路径假设。
每一条重要结论必须给出:文件路径 + 类/函数或结构名称 + 适当行范围或 commit + 相关调用顺序。核心论断不得只引用历史文档或本任务描述。
允许纯只读 Git/文本搜索,不要求也不允许额外建立实验分支、修改 Native/JS/Kotlin/测试代码、插桩、添加日志、运行 Jest、运行测试、Gradle、CMake/Ninja/Bazel、ADB 或重新安装 App。不得改 NavSea、Integration 或正式 release/tag。
六、最终必须提供的结论矩阵
每个问题必须选择明确判定,而不是只罗列建议:
| 维度 | 可选结论 |
|---|---|
| 能否定位 Placement 事件来源 | 现有数据可区分 / 现有数据不足 / 条件性可区分 |
| 能否证明 R0 的实际视觉结果未变化 | 已能证明 / 需扩展内部安全证据 / 不能按段安全证明 |
| 现有 Gate 是什么性质 | 正确的设计保守限制 / 明确可证的过度阻塞 Bug / 混合 / 证据不足 |
| 缓存失效的主要责任边界 | Native Placement 数据模型 / Native Gate 判定 / 当前跨段碰撞语义 / Host Style 组合 / 多因素 / 未确定 |
| 可选后续方向 | 无需代码调整 / Native 内部诊断补强 / Native 内部安全判据设计 / 宿主层序方案需协调 / 需真机对照实验 |
如果判断是 Bug,必须指出违背了哪项既有语义/可复现的状态不变量;如果判断是安全限制,必须指出缺少何种证明才不能放宽。如有多个阻塞项,按必要性和因果顺序排序,避免“修第一个之后才继续猜下一个”。
七、报告与交接产物
只允许新建/更新以下本 Step 文档(不改现有源码):
docs/20_调查/R0_Placement跨段归因与缓存安全边界调查_v1.md(主报告);docs/50_Step记录/STEP-110_R0_Placement跨段归因只读调查_v1.md(状态及完成项);docs/报告/STEP-110_R0_Placement跨段归因只读调查_Codex完成报告_v1.md(执行报告);粒子开发记录.md(简短追加式记录)。
调查主报告必备章节:
- V23 tag / 当前 main 基线对照,说明是否有相关行为变化;
- Q1~Q4 的逐条答案及代码证据;
- 数据流/状态流:Placement 事件 → 全局/局部状态 → R0 安全判定 → Cache Build/Reuse/Fallback → Fast Path;
- 七类反事实场景矩阵,明确跨源碰撞、Fade、Annotation 的影响;
- 已确定事实、假设、证据不足之处三栏;
- 结论矩阵、根因优先级、最小下一步验证建议;
- 若需调整公共 Contract / API,则仅提出 Integration 阻塞,不自行实施。
完成报告必须逐项按“已完成 / 未完成 / 无法验证”回答任务项并说明原因;记录实际检查范围、当前 branch/HEAD、Git 提交及推送信息。不得用“源码已读”代替代码证据。
状态判定:只读因果审计证据完整才可标为 调查 PASS(不等于修复 PASS);否则 PARTIAL/BLOCKED 并列出缺失项。严禁声称“Native 已修复”、“R0 已缓存”或“CPU 已下降”。
八、Git 收尾与执行界限
- 本任务只负责调查。Codex/粒子项目未经用户后续明确授权,不得实施任何缓存、Placement、Fast Path 逻辑修改。
- 完成相关文档后,仅提交本 Step 新增报告、Step 记录及追加的开发记录;保留所有无关 dirty/untracked 文件,不得强制清理。
- 将本任务相关文档 scoped commit 到正式主线
particle/main并 push 到公开远端origin/particle/main。禁止 force push、改写历史、推送 upstream 或增加无关文件。 - 完成报告必须给出实际 commit hash、commit message、push 结果、远端分支;push 失败不得宣称完成,应明确报告阻塞。
- 本 MD 是交给粒子项目执行的待办合同。写入任务书本身不代表调查已执行、已验证或已得出结论。
- 本任务不包含 Jest,不涉及原生编译、测试执行或 Android 设备操作。
九、停止条件
遇到以下情形须停留在调查层,提交 PARTIAL/BLOCKED 事实,不得扩大实现:
- V23 tag 与当前代码差异导致无法确认实际执行版本;
- Placement 影响关系必须依赖运行时数据,静态源码无法证明;
- 证明缓存安全需新增 per-segment collision/placement fingerprint 或改写 Core 算法;
- 需要改变对外 Native/RN 公共接口或跨项目责任;
- 需要 NavSea 配合修改 Style、增加调试或重新编译/测试;
- 所需证据缺失或与 STEP-090/102/106 的历史结论相冲突。
出现以上情况,在报告中给出最小下一步任务建议,等待用户/Integration 决定;不得在本任务中直接实施。