# STEP-102 RenderSegment 无 Placement 段局部复用 Codex 任务 v1 ## 1. Step 编号和目的 STEP-102:修复 full CPU 多 Retained Segment 下 placement aggregate gate 的不必要扩散,使**结构上不具备 placement 能力**的 Retained Segment 能在其他 placement-bearing Segment fallback/live 时继续独立 composite/reuse。 本 Step 的设计依据: `docs/20_调查/RenderSegment多Retained段全局Placement门槛_粒子管理员审查说明_v3.md`。 ## 2. 当前已冻结基线 - 仓库:`/Users/tei/dev/MapLibreParticleLab-step102` - branch:`step102-placement-free-retained-locality` - start HEAD:`6df21dac38f072c5ad35b8dfc7ec5217509602bc` - upstream base:MapLibre Native core 既有冻结基线,不升级 - V19/V20 release worktree:冻结,只读,不修改 - STEP-100 source-scoped locality:必须保持 - STEP-101 teardown 修复:必须保持 - Fast Path:本 Step 不修改 - C-001:不升级 ## 3. 本 Step 目标 必须实现: 1. 增加结构性 placement-capable range 查询; 2. full CPU 每个 Retained Segment 独立计算 placement gate; 3. placement-free Retained 不再被其他 Segment 的 placementChanged/symbolFadeChange 纯 aggregate gate 拖入 fallback; 4. placement-bearing Retained 继续使用现有保守 placement gate; 5. 从 full CPU `globalLiveFallback` 移除纯 aggregate placement 条件; 6. 保持真正全局 fail-closed 条件; 7. diagnostics 增加结构 placement、per-segment gate、实际 composite/live 与全局 main-buffer execution 信息; 8. RN diagnostics TS 类型做 additive 扩展; 9. 增加对应 C++ 测试源码与 Android Validation 场景源码; 10. 不改变 Style Z-order、mixed executor、C-001 和 RN method surface。 ## 4. 非目标 / 禁止事项 禁止: - placement-bearing Segment 之间的局部碰撞缓存; - per-segment collision graph / symbol fade / placement fingerprint; - Fast Path 改造; - multi-continuous Fast Path; - 重写 `visitRenderSegmentExecution()`; - 修改 NavSea; - 新增 NavSea 私有 Native API; - 修改 C-001; - 修改 V19/V20 release worktree/tag; - 升级 MapLibre、NDK、Gradle、AGP、Java、Node 或其他工具链; - 为通过测试降低 fail-closed 门槛; - Android Gradle/build、APK/AAR build、ADB、设备操作; - Jest。用户未要求 Jest,本任务不得新增或执行 Jest。 ## 5. 允许修改范围 生产代码优先限制在: - `src/mbgl/renderer/render_orchestrator.hpp` - `src/mbgl/renderer/render_orchestrator.cpp` - `src/mbgl/renderer/renderer_impl.cpp` - `include/mbgl/renderer/render_segment.hpp` - `src/mbgl/renderer/retained_underlay_runtime_state.hpp` - `src/mbgl/renderer/render_segment_json.hpp` - `packages/maplibre-particle-rn/src/types.ts` 测试/Validation 允许: - `test/renderer/retained_underlay_cache.test.cpp` - 与现有 Particle Validation 场景直接相关的最小 Android Test App 文件 文档允许: - 本任务书 - `docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md` - `docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md` - `粒子开发记录.md` - v3 审查说明只读,除非发现明确事实错误;若需改,停止并先报告 如果实现必须扩大生产代码范围,先停止并报告原因,不得自行扩张架构。 ## 6. 禁止修改范围 - NavSea 仓库 - `navsea-particle-integration` contract/RFC/ADR - Fast Path 逻辑、`tryRenderParticleFastFrame()`、`singleContinuousSegment()` 语义 - `retainedRangeUsesPlacement()` 现有动态语义 - mixed executor 算法 - Source `isLoaded()` 定义 - STEP-100 source revision/locality 语义 - STEP-101 teardown 生命周期语义 - renderer/backend 架构 - release/version/tag/publish 坐标 ## 7. 实施要求 ### 7.1 结构性 placement-capable 查询 新增 full CPU retained 专用查询,必须基于 layer 结构,而不是当前帧 placementData。 最小保守语义: - range 中存在 `symbol` layer → placement-capable - 无 `symbol` layer → placement-free - custom/custom-drawable 继续由 unsupported gate 处理 不得用 `needsPlacement()==false` 证明 placement-free。 ### 7.2 per-segment placement gate 每个 Retained Segment 至少形成两个明确事实: - structural placement capability - current full-CPU placement gate result placement-free Segment 不受纯 global placement gate 阻塞。 placement-bearing Segment 本 Step 继续沿用旧保守 gate,不承诺稳定后 reuse。 变量/字段命名不得把 `symbolFadeChange==0` 错称为严格 placement stable。 ### 7.3 full CPU mixed execution `segmentSupported` 改为使用对应 Segment placement gate。 `globalLiveFallback` 仅移除纯 aggregate placement 条件,其他真正 global 条件继续保留。 不得重写 `visitRenderSegmentExecution()`。 ### 7.4 fallback reason `static-placement` 必须按 Segment 自身 placement capability/gate 判定,不能从 aggregate reason 无差别传播。 ### 7.5 diagnostics 每个 Segment 最少新增等价语义: - `placementCapable` - `placementGatePassed` - `actualExecution = composite | live` 全局最少新增等价语义: - `placementChanged` - `symbolFadeChange` - `placementTransitionActive` - `crossSourceCollisions` - `mainBufferExecutionMode = mixed | global-live` - `globalLiveFallbackReason` `actualExecution` 必须反映本帧 main-buffer 最终实际执行,不能根据 cache finalDecision 推导。 Diagnostics 查询必须无副作用、不得推进 revision。 ### 7.6 RN 类型 只扩展现有 diagnostics 返回类型,不新增 method,不改变 `setRenderSegmentPlan()` 输入 contract。 Android/iOS Shared Core JSON 语义保持一致。 ## 8. 构建要求 Codex 本阶段**不得执行任何 Android 编译/Gradle/APK/AAR build**,也不得启动长时间 CMake/Ninja/Bazel 构建。 Codex 完成代码后只需提供精确验证命令,由后续 RDC/用户按规则执行。其中 Android 编译由用户手工执行。 Codex 可执行的机械静态检查仅限: - `git diff --check` - 只读 grep/rg/git diff/status - 不产生构建产物的格式/静态检查(若仓库已有且无需安装依赖) 不得安装或升级系统依赖来制造测试 PASS。 ## 9. 测试要求 Codex 必须新增/补强测试源码,但本阶段不执行大型测试。 至少覆盖: 1. placement-free R0 + placement-bearing R1:R0 可 composite,R1 live; 2. 含 symbol 但当前 placementData 为空:仍判定 placementCapable=true; 3. 两个 placement-free Retained:持续 reuse/composite; 4. source-local fading/mutation 回归不误伤 R0; 5. placement-bearing 在 transition disabled / `symbolFadeChange=1` 等状态仍不被本 Step 放宽; 6. 真正 global gate 继续 global-live/fail-closed; 7. topology 变化释放旧 resource; 8. cache decision=reuse 但 global-live 时,diagnostics 的 actualExecution 必须为 live; 9. diagnostics JSON/TS 字段语义一致且查询无副作用。 Android Validation 场景应能在后续手工构建后明确输出 STEP-102 验收所需字段,不依赖 NavSea。 ## 10. 验收标准 代码审计门槛: - [ ] 新增结构性 placement-capable 查询 - [ ] 未改变 `retainedRangeUsesPlacement()` 旧语义 - [ ] full CPU per-segment placement gate 生效 - [ ] placement-bearing 继续保守 - [ ] `globalLiveFallback` 只移除纯 aggregate placement 条件 - [ ] 真正 global gate 保留 - [ ] mixed executor 未重写 - [ ] Fast Path 无语义修改 - [ ] per-segment fallback reason 正确 - [ ] diagnostics 有 actualExecution 与 main-buffer mode/fallback reason - [ ] RN method surface 不变 - [ ] C-001 不变 - [ ] 测试源码覆盖设计矩阵 - [ ] `git diff --check` PASS 运行态 PASS 不在 Codex 阶段宣称。Android 手工编译与真机验证未完成前,STEP-102 状态只能写“代码完成 / 等待验证”或同等非 PASS 状态。 ## 11. Git 要求 - 工作分支:`step102-placement-free-retained-locality` - 禁止修改 particle/main 工作区 - 禁止 `git add -A`、`git add .`、`git reset --hard`、`git clean` - 只 scoped staging 本任务文件 - 不提交无关 dirty/untracked 文件 - Codex 可在实现完成、静态检查通过后创建 scoped implementation commit,但**不得 merge 到 particle/main、不得 push release 分支/tag、不得发布制品** - 是否 push/merge 由后续独立验收决定 ## 12. 必做输出 Codex 完成后必须交付: 1. 生产代码修改; 2. C++ 测试源码; 3. Android Validation STEP-102 场景源码/日志字段; 4. `docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md`; 5. `docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md`; 6. 追加 `粒子开发记录.md`; 7. 精确列出后续验证命令; 8. 明确列出所有 NOT RUN / BLOCKED 项; 9. Git diff/status/commit(若创建)事实。 ## 13. 执行报告完整文件名 固定: `docs/报告/STEP-102_RenderSegment无Placement段局部复用_Codex完成报告_v1.md` 同主题后续报告只递增 `_v2/_v3`,不得另造近义文件名。 ## 14. 执行报告固定内容 至少包含: 1. 执行结论:只能按实际写代码完成/等待验证、PARTIAL、BLOCKED 或 FAIL;未运行 Android 不得写运行态 PASS 2. Git 基线:branch/start HEAD/end HEAD/status 3. 实际修改文件 4. 新增文件 5. 实现内容逐条对照任务书 6. 与 v3 设计差异 7. Fast Path / mixed executor / C-001 未修改审计 8. diagnostics 新字段与语义 9. 测试源码覆盖矩阵 10. 实际执行的静态检查 11. 未执行的 build/test/Android/设备项目 12. 用户手工 Android 构建命令 13. 后续 RDC/真机验收命令与硬门槛 14. 已知风险与未完成事项 15. Git commit 信息(若有) ## 15. 阻塞与停止条件 遇到以下任一情况必须停止扩大修改并报告: - 结构性 placement capability 不能仅靠既有 layer type 安全判定,需要新增更大公共抽象; - 必须修改 Fast Path 才能完成本任务; - 必须重写 mixed executor; - 必须改变 collision/Placement 核心算法; - 必须修改 C-001 / RN method surface; - 必须修改 NavSea; - 必须扩大到 renderer/backend 架构重构; - 发现 global revision 仍有未预期的 placement 推进,需要新设计; - 需要升级工具链/依赖; - 需要删除或弱化既有测试/安全门槛。 若实现范围保持在 v3 冻结边界内,可直接完成代码并停在“等待手工构建/运行验证”。