From 12827489f4c377175554562632129df125c0a556 Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Fri, 11 Sep 2026 09:01:20 +0800 Subject: [PATCH] docs: record STEP-069 v2 field ingress --- ...Android_JNI_RN_v2多Plane入口_Codex任务_v1.md | 264 ++++++++++++++++++ ...Lab_V3-05_Android_JNI_RN_v2多Plane入口_v1.md | 23 ++ ...oid_JNI_RN_v2多Plane入口_Codex完成报告_v1.md | 26 ++ 粒子开发记录.md | 6 + 4 files changed, 319 insertions(+) create mode 100644 docs/40_任务/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex任务_v1.md create mode 100644 docs/50_Step记录/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_v1.md create mode 100644 docs/报告/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex完成报告_v1.md diff --git a/docs/40_任务/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex任务_v1.md b/docs/40_任务/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex任务_v1.md new file mode 100644 index 000000000..87cbecb17 --- /dev/null +++ b/docs/40_任务/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex任务_v1.md @@ -0,0 +1,264 @@ +# STEP-069 MapLibreParticleLab V3-05 Android/JNI/RN v2 多 Plane 入口 — Codex 任务 v1 + +## 1. 任务目标 + +基于当前 `particle/main` HEAD `9e9ea07bc74633714836aa4fff4e963109f4e3b9`,完成 `maplibre-particle-field/v2` 从 RN → Android Kotlin → Java Host facade → JNI → `RasterArraySource` → 现有 Core V3 Snapshot/Timeline 的明确多 plane 二进制入口。 + +本任务只做通用 Scalar/Vector Field runtime 的 Host ingress 与已经冻结的 renderer 配置桥,不引入 Wind/Wave/Rain/Tide provider/business 逻辑,不解析 NSFT/PMTiles,不改 Timeline/T0/T1/MIX/rollover/lifecycle 算法。 + +开始前必须完整阅读:`AGENTS.md`、`PARTICLE_BASELINE.md`、`docs/00_项目规范/`、STEP-065/066/067/068 的 Step/报告,以及当前实际源码。不得按记忆重建。 + +## 2. 当前已确认基线 + +- RN package:`packages/maplibre-particle-rn` 当前版本 `13.4.1-particle.2`。 +- `.2` 公共 `FieldRuntime.submitField(reactTag, metadataJson, payloadFileUri)` 内部仍映射 `submitWindField` 单文件 ABI。 +- Kotlin `WeatherRuntimeBridgeModule` 当前只读取一个本地 payload,单 payload 上限 64 MiB。 +- Java `WeatherRuntime.submitWindField(metadataJson, byte[])` → `MapLibreMap.submitRasterArraySourceHostField(...)`。 +- JNI `NativeMapView::submitRasterArraySourceHostField(...)` 当前只转一个 `byte[]` 为 `std::vector`。 +- `RasterArraySource::submitHostField(metadata, vector)` 是 v1 legacy ingress。 +- Core 已有 `ParticleFieldPayloadBundle { scalar?, vector?, validity? }` 与 `LocalParticleFieldFeed::load(metadata, bundle)`,但 `RasterArraySource` 尚无 v2 bundle overload。 +- STEP-067 已有 `WeatherColorLayer::FieldValueSource { Scalar, VectorMagnitude }`,尚无 Android/RN setter。 +- STEP-068 已有 `raster-particle-advection-scale`,尚无 Android/RN setter。 + +## 3. v2 RN 公共 API + +将 package 版本递增到 **`13.4.1-particle.3`**,不得覆盖或继续宣称 `.2`。 + +新增并导出 provider-neutral 类型: + +```ts +type FieldPayloadRefs = Readonly< + { validityFileUri: string } & ( + | { scalarFileUri: string; vectorFileUri?: string } + | { scalarFileUri?: string; vectorFileUri: string } + ) +>; + +type FieldValueSource = "SCALAR" | "VECTOR_MAGNITUDE"; +``` + +`.3` 的主入口冻结为: + +```ts +FieldRuntime.submitField(reactTag, metadataJson, payloadRefs) +FieldRuntime.clearFields(reactTag) +FieldRuntime.setFieldValueSource(reactTag, source) +FieldRuntime.setParticleAdvectionScale(reactTag, scale) +``` + +`submitField` 不得再接受 JS number[]、Base64 或巨大 JSON payload。 + +为了保留 v1 thin compatibility ingress,可保留现有 native/internal `submitWindField(metadata, singlePayload)`,并在 `.3` 公共层提供命名明确的 legacy 入口(例如 `submitLegacyVectorField`);不得让 v1/v2 共用一个模糊单 payload 形状。README/CHANGELOG 必须明确 `.2` 与 `.3` 差异。 + +## 4. payloadRefs 文件规则 + +v2 必须使用三个语义明确的 local file reference: + +- `validityFileUri`:必填; +- `scalarFileUri`:可选; +- `vectorFileUri`:可选; +- scalar/vector 至少一个存在,否则在 Kotlin bridge fail-closed。 + +只允许 `file://` 或绝对本地路径,沿用现有 local-file 安全规则。 + +在实际读文件前先完成所有路径、可读性、文件长度检查,再读取;避免读到一半才发现 aggregate 超限。 + +冻结本桥接层 v3 初版内存上限: + +- metadata UTF-8 ≤ 1 MiB(沿用现状); +- 每个存在的 plane 必须非空; +- **三个 plane 文件总字节数 ≤ 64 MiB**; +- 单文件自然也不得超过 64 MiB; +- 总长度计算必须防溢出; +- Core 仍负责按 metadata 声明验证每 plane exact byteLength/encoding/layout/validity。 + +不得把缺失 scalar/vector 伪造为零数据文件。validity 必须显式存在。 + +## 5. Android/Kotlin bridge + +在 `WeatherRuntimeBridgeModule` 中新增 generic v2 submit 方法,命名可以继续受现有 TurboModule/codegen seam 限制,但语义必须明确为 Field v2,不能叫新的 Wind-only API。 + +推荐流程: + +1. 校验 metadata; +2. 校验 refs presence; +3. resolve 三个 local file; +4. stat 全部存在 plane,计算 aggregate; +5. aggregate ≤ 64 MiB 后才逐个 bounded read; +6. 调 Java `WeatherRuntime.submitField(...)`; +7. Promise 返回现有 `FieldSubmitResult` name。 + +不得保存 reactTag/runtime/timeline 第二份状态,不改变现有 per-view lookup 与生命周期。 + +legacy `submitWindField` 可以保留作为 thin v1 compatibility,不得删除导致旧 `.2` native seam 无法理解。 + +## 6. Java Host facade + +`WeatherRuntime` 新增 provider-neutral: + +- `submitField(metadataJson, scalarBytes?, vectorBytes?, validityBytes)`; +- `clearFields()`(旧 `clearWindFields()` 可作为 deprecated/thin alias); +- `setFieldValueSource(...)`; +- `setParticleAdvectionScale(float)`。 + +不得在 Java 根据 `fieldId`、Wind/Wave/Rain/Tide 名称猜 renderer 行为。 + +`setFieldValueSource` 只接 `SCALAR` / `VECTOR_MAGNITUDE`;`setParticleAdvectionScale` 必须 finite 且 >0。二者只控制已有 renderer config,不改 Source timeline。 + +WeatherColor 内部历史 `speedMps` 命名若本任务不影响功能,可保留为兼容技术债,禁止借机大规模重命名。 + +## 7. NativeMap / JNI + +新增明确的 v2 JNI 方法,不得重载旧单 payload 产生 ABI 歧义。 + +优先使用三 plane 参数:`scalar byte[]?`、`vector byte[]?`、`validity byte[]`。必须先检查当前 jni.hpp 对 nullable primitive array 的实际支持;若 nullable array 在当前 binding 容易产生注册/调用风险,可以改用**明确 v2 container 参数结构**,但必须: + +- 不与 v1 单 payload 混淆; +- 明确记录 offsets/lengths; +- 不在 JS 层构造巨大 container; +- Kotlin/Java → JNI 后最终恢复成 `ParticleFieldPayloadBundle`。 + +不允许因为参数处理困难而用“空 scalar/vector 字节数组代表缺失”去绕过语义,除非在 ABI 层有明确 presence flags 且 Core bundle 恢复为 `std::nullopt`。 + +JNI 必须最终调用新的 `RasterArraySource::submitHostField(metadata, ParticleFieldPayloadBundle)`。 + +## 8. RasterArraySource 最薄 v2 overload + +新增: + +```cpp +submitHostField(const std::string&, const particle::ParticleFieldPayloadBundle&) +``` + +或等价明确 overload。 + +它必须调用现有 `LocalParticleFieldFeed::load(metadata, bundle)`;v1 overload 继续调用 legacy load/normalize。 + +两条 ingress decode 后必须进入**同一份** duplicate / monotonic / compatibility / pending initial T0 / initial window / next snapshot 提交流程。应提取最小公共 helper 避免复制 Timeline 状态机,但不得重写 Timeline。 + +日志改为 provider-neutral plane presence/bytes,不得假称所有 payload 为 `interleaved-uv`。legacy v1 日志可明确标注 legacy/vector-only。 + +## 9. FieldValueSource Android/JNI bridge + +Core 已有 `WeatherColorLayer::setFieldValueSource()`,本任务只加最薄 Android/JNI Host setter,例如以稳定 int/enum code 表达: + +- `0 = SCALAR` +- `1 = VECTOR_MAGNITUDE` + +非法值 fail-closed。 + +不得新增天气业务 enum。该 setter 不重传 Field、不改变 Timeline。 + +## 10. advectionScale Android/RN bridge + +利用 STEP-068 已有 `raster-particle-advection-scale` style property,Java Host 可通过现有 `setStyleLayerFloatProperty` 设置;如无需新 JNI 就不要新增 JNI。 + +RN 公开 `setParticleAdvectionScale()`;必须 finite、>0,最终只修改 renderer property,不重传 field、不清 Timeline/Trail/State。 + +## 11. 必须验证的行为 + +至少覆盖: + +1. v2 scalar-only bundle 可 decode/submit; +2. v2 vector-only VELOCITY 可 decode/submit; +3. v2 scalar+vector DIRECTION 可 decode/submit; +4. 缺 validity 拒绝; +5. scalar/vector 都缺拒绝; +6. metadata 声明与 plane presence/长度不一致由 Core 拒绝; +7. v1 legacy vector-only ingress 仍通过 thin normalize; +8. v1 与 compatible v2 vector-only 可进入同一个 Runtime/Timeline 契约; +9. T0/T1 channel presence 或 vector semantics 不同继续拒绝; +10. aggregate local file size >64 MiB 在读入前拒绝; +11. 非 file URI / 相对路径拒绝; +12. FieldValueSource 非法值拒绝; +13. advectionScale <=0 / NaN / Inf 拒绝; +14. `.3` TypeScript public type 不允许 payloadRefs 同时缺 scalar/vector; +15. legacy API 明确命名,不与 v2 `submitField` 形状混淆。 + +## 12. 测试与静态验证 + +本任务**不执行 Android Gradle、AAR、APK、ADB,也不执行 Jest**。 + +允许并要求: + +- Core/RasterArraySource 相关 C++ 精确对象编译; +- 相关 C++ 过滤测试,补最小测试覆盖 v2 Source submit 与 legacy regression; +- `ninja -C build-linux-opengl -j3 mbgl-test mbgl-test-runner` 仅当变更触发 Core 并且已有 build 可用; +- `git diff --check`; +- RN package TypeScript `tsc --noEmit` / 项目现有等价静态检查; +- 检查 TurboModule spec 与 Kotlin override 参数一致性; +- 可运行无需 Gradle 的 codegen/文本生成检查,但不得为了验证启动 Android build。 + +所有 noisy build 遵守 `$build-output-throttle`。 + +由于 Android 真正 Java/Kotlin/JNI 编译由用户后续 V3-08 手工统一执行,本 Step 不能声称 Android compile PASS。若静态审计仍存在签名不确定性,报告必须写明。 + +## 13. 明确禁止 + +不得: + +- Android Gradle/AAR/APK/ADB; +- Jest; +- 修改 WeatherV2/NavSea; +- 解析 NSFT、PMTiles 或 provider manifest; +- 加 Wind/Wave/Rain/Tide enum/if 分支; +- 从 Wave height/period 推断粒子速度; +- 引入第二 scalar 或 N-channel; +- 改 Timeline/T0/T1/MIX/rollover/playback 算法; +- JSI/zero-copy 大重构; +- 删除 `.2` 已冻结 legacy native ABI; +- 修改 STEP-062 两处用户 dirty 文档; +- 清理历史 untracked/build/cache/tgz。 + +## 14. 必做文档 + +新增/更新: + +- 本任务书 `docs/40_任务/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex任务_v1.md` +- `docs/50_Step记录/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_v1.md` +- `docs/报告/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex完成报告_v1.md` +- `packages/maplibre-particle-rn/README.md` +- `packages/maplibre-particle-rn/CHANGELOG.md` +- 追加 `粒子开发记录.md` + +全部文档中文说明为主,代码/API/命令保留英文。 + +任务完成后逐项报告“已完成 / 未完成 / 无法验证”,并明确 Android 编译未执行。 + +## 15. 状态判定 + +若 Core/Linux/TS 静态验证与 contract 检查满足要求,可标记: + +`IMPLEMENTED / WAITING_ANDROID_VALIDATION` + +**不得在本 Step 标记 Android CLOSED/PASS**,因为按照项目规则 Android 编译/实体机验收统一留到 V3-08。 + +该状态允许进入 V3-06 fixtures,只要不存在已知 ABI/类型阻塞。 + +## 16. Git 收尾 + +本任务修改代码,必须 scoped commit + push `origin/particle/main`。 + +提交前检查 `git status --short`,只暂存 STEP-069 实际文件。严禁 `git add .` / `git add -A`。 + +STEP-062 两处 tracked dirty、所有历史 untracked、`.codex-build-logs/`、旧 tgz/build 目录一律不得提交。 + +允许 1 个实现 commit + 1 个文档 handoff commit。 + +完成报告必须记录: + +- implementation commit hash/message; +- handoff commit hash/message(若有); +- push result; +- remote branch; +- Final HEAD; +- `HEAD == origin/particle/main`; +- 未纳入的既有 dirty 内容摘要。 + +push 失败不得声称任务完成。 + +## 17. 执行回填(2026-09-11) + +- 已按本任务实现 `.3` v2 refs、Kotlin/Java/JNI/Core bundle ingress、`FieldValueSource` 与 `advectionScale` 桥接;v1 ABI 保留为明确 legacy ingress。 +- 未执行 Android Gradle、AAR、APK、ADB 或 Jest;Android 编译留给 V3-08。 +- 结果状态:`IMPLEMENTED / WAITING_ANDROID_VALIDATION`。最终 commit/push 与允许验证结果见本 Step 记录和完成报告。 diff --git a/docs/50_Step记录/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_v1.md b/docs/50_Step记录/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_v1.md new file mode 100644 index 000000000..954c8b629 --- /dev/null +++ b/docs/50_Step记录/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_v1.md @@ -0,0 +1,23 @@ +# STEP-069 MapLibreParticleLab V3-05 Android/JNI/RN v2 多 Plane 入口 + +状态:完成(IMPLEMENTED / WAITING_ANDROID_VALIDATION) + +## 已完成 + +- [x] RN 包升为 `13.4.1-particle.3`,导出 `FieldPayloadRefs`、`FieldValueSource`;v2 主入口只接受 refs。 +- [x] 保留 v1 `submitWindField` ABI,并提供明确的 `submitLegacyVectorField` 公共兼容入口。 +- [x] Native TurboModule Spec 改为 codegen 支持的三个明确 string plane 参数;公共 `FieldRuntime.submitField(..., FieldPayloadRefs)` 保持不变,空 scalar/vector string 仅为 Native ABI 的 optional marker。Kotlin 在读取前校验 validity、local file、非空和三 plane aggregate 64 MiB;Java/JNI 用 presence flags 和长度恢复 optional bundle。 +- [x] Java `WeatherRuntime.submitField` 给 nullable scalar/vector 标注 `@Nullable`,并独立拒绝 total 超过 64 MiB,避免绕过 Kotlin 后分配 oversized packed array。 +- [x] `RasterArraySource` v1/v2 decode 后共用同一 duplicate、monotonic、compatibility、initial-window 与 Timeline 路径。 +- [x] 桥接 `SCALAR|VECTOR_MAGNITUDE` 与 positive finite `advectionScale`,只更新既有 renderer config。 +- [x] Core source 测试覆盖三种合法 v2 bundle、缺 validity/no channel 与 semantics incompatibility,以及 v1 legacy 与 compatible v2 vector-only 进入同一 `RasterArraySource` Timeline。 + +## 范围与验证 + +未改 WeatherV2、NavSea、Timeline/T0/T1/MIX/rollover/lifecycle,也未改 STEP-062 dirty 或无关 untracked 内容。以下均经 build-output-throttle:外部复核指定的 `combine-js-to-schema-cli.js /tmp/step069-schema.json packages/maplibre-particle-rn/src/NativeWeatherRuntimeBridge.ts` 实际 PASS;`./node_modules/.bin/tsc --noEmit -p packages/maplibre-particle-rn/tsconfig.json` PASS;`source.test.cpp.o` 精确编译 PASS;`ninja -C build-linux-opengl -j3 mbgl-test` 重链 PASS;`Source.HostFieldV2BundleUsesTheSameTimelineIngress:Source.HostFieldLegacyAndCompatibleV2VectorOnlyShareOneTimeline` 2/2 PASS。`git diff --check` PASS。Android Gradle/AAR/APK/ADB、Jest 均未执行;Android compile 留给 V3-08,不能标记 Android PASS。 + +## Git 收尾 + +- implementation commit:`148bf80fe41ba566de6c1d4b439cfe372a8a453c`(`feat: add v2 multi-plane field ingress`)。 +- 本 Step 仅显式暂存实现文件;STEP-062 两处用户 dirty、历史 untracked、`.codex-build-logs/`、旧 tgz/build/cache 均未纳入。 +- 文档 handoff commit 与 push/Final HEAD 在完成报告最终提交后回填。 diff --git a/docs/报告/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex完成报告_v1.md b/docs/报告/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex完成报告_v1.md new file mode 100644 index 000000000..ca9d53f9b --- /dev/null +++ b/docs/报告/STEP-069_MapLibreParticleLab_V3-05_Android_JNI_RN_v2多Plane入口_Codex完成报告_v1.md @@ -0,0 +1,26 @@ +# STEP-069 MapLibreParticleLab V3-05 Android/JNI/RN v2 多 Plane 入口 Codex 完成报告 + +结论:IMPLEMENTED / WAITING_ANDROID_VALIDATION。 + +## 已完成 + +`@navsea/maplibre-particle-rn` 已升至 `13.4.1-particle.3`。v2 `FieldRuntime.submitField` 仍接收必填 validity、可选 scalar/vector 的 `FieldPayloadRefs`;仅 Native TurboModule ABI 改为 `validityFileUri, scalarFileUri, vectorFileUri` 三个明确 string 参数,空 scalar/vector string 只表示 ABI optional marker。Kotlin 在读入前检查 local-file、非空及 aggregate 64 MiB。Java 的 explicit packed v2 container 只存在于 Java/JNI,使用 plane presence flags 和 lengths;JNI 恢复 `ParticleFieldPayloadBundle`,JS 不构造大容器。Java 对 nullable scalar/vector 有 `@Nullable` 注释,并在 Java facade 额外拒绝 total 大于 64 MiB,防止绕过 Kotlin 的 oversized packed allocation。v1 ABI 保留,`.3` 用 `submitLegacyVectorField` 明确标识。 + +Core v1/v2 ingress decode 后共用 Timeline 提交 helper,未改 duplicate、T0/T1、MIX、rollover 或生命周期。`setFieldValueSource` 仅接受 0/1 对应 `SCALAR|VECTOR_MAGNITUDE`,`setParticleAdvectionScale` 仅接受 finite 且大于零,均只改 renderer property。 + +## 验证与未完成 + +- `git diff --check`:PASS。 +- 外部复核指定的实际 codegen 命令 `node integration/react-native/MapLibreParticleRNTestHost/node_modules/@react-native/codegen/lib/cli/combine/combine-js-to-schema-cli.js /tmp/step069-schema.json packages/maplibre-particle-rn/src/NativeWeatherRuntimeBridge.ts`:PASS。 +- `./node_modules/.bin/tsc --noEmit -p packages/maplibre-particle-rn/tsconfig.json`:PASS。 +- `source.test.cpp.o` 精确编译与 `ninja -C build-linux-opengl -j3 mbgl-test` 重链:PASS;`Source.HostFieldV2BundleUsesTheSameTimelineIngress:Source.HostFieldLegacyAndCompatibleV2VectorOnlyShareOneTimeline`:2/2 PASS,明确覆盖 legacy v1 与 compatible v2 vector-only 的同一 Timeline ingress。 +- 上述 build/codegen/test 命令均经 build-output-throttle;Android Kotlin/Java/JNI 签名只做源码一致性核对,未运行 Android 编译。 +- Android Gradle、AAR、APK、ADB 与 Jest 均按任务禁止未执行。Android Kotlin/Java/JNI compile 和设备验证必须在 V3-08 完成,故不标记 Android CLOSED/PASS。 + +## Git 收尾 + +- implementation commit:`148bf80fe41ba566de6c1d4b439cfe372a8a453c`,message:`feat: add v2 multi-plane field ingress`。 +- handoff commit:待本报告提交后由最终 Git 收尾回填/确认。 +- push:待 handoff commit 后执行。 +- remote branch:`origin/particle/main`。 +- 未纳入:STEP-062 两处用户 dirty、历史 untracked、`.codex-build-logs/`、旧 tgz/build/cache。 diff --git a/粒子开发记录.md b/粒子开发记录.md index 3f315714d..dfca7f6b5 100644 --- a/粒子开发记录.md +++ b/粒子开发记录.md @@ -653,3 +653,9 @@ WeatherColorLayer 的 `ParticleGpuValidationUBO` designated initializer 补齐 ` # 2026-09-11 STEP-068 收尾:WeatherColor UBO 漏初始化修复后,最终受影响精确对象 PASS;`mbgl-test` / `mbgl-test-runner` 完整 Linux OpenGL 目标重编译与重链 PASS;STEP-068 相关 `Source.ParticleFieldV3*:Layer.RasterParticle*` 8/8 PASS;`git diff --check` PASS。额外扩大过滤范围发现基线既有 WeatherColor 测试末尾断言逻辑错误,已确认不由 STEP-068 引入,未混入本任务修复。STEP-068 正式 CLOSED / PASS;Android/Jest 未执行。 # 2026-09-11 STEP-068 Git:主实现 `f3c33c67275b24f61b80924abbb9d10d68b2cb7c`(`feat: add direction particle advection`)已成功 push 到 `origin/particle/main`,推送后 HEAD 与远端一致;STEP-062 用户修改与历史无关文件未提交。 + +# 2026-09-11 STEP-069:实现 RN `.3` 的 `maplibre-particle-field/v2` 多 plane ingress。`FieldPayloadRefs` 强制 shared validity、scalar/vector 至少一个,Kotlin 在读取前完成 local file 与 aggregate 64 MiB 校验;Java/JNI 以 presence flags/lengths 的明确 container 恢复 Core optional bundle。v1 单 vector ABI 保留为 `submitLegacyVectorField`。同时桥接 SCALAR/VECTOR_MAGNITUDE 与正 finite `advectionScale`,不改 Timeline、WeatherV2、NavSea 或 STEP-062。Android Gradle/AAR/APK/ADB/Jest 未执行,状态 `IMPLEMENTED / WAITING_ANDROID_VALIDATION`。 + +# 2026-09-11 STEP-069 复核修正:Native TurboModule Spec 移除 codegen 不支持的外部 `FieldPayloadRefs` object 参数,改用明确的 validity/scalar/vector string ABI;公共 `FieldRuntime.submitField(..., FieldPayloadRefs)` 不变,空 scalar/vector 仅为 bridge optional marker。外部复核指定 codegen schema 命令与 package `tsc` 均实际 PASS。Java facade 对 nullable scalar/vector 明确 `@Nullable`,并补 total <=64 MiB 防御;新增 Core 最小测试确认 v1 legacy 与 compatible v2 vector-only 进入同一 RasterArraySource Timeline,精确编译、`mbgl-test` 重链和过滤测试 2/2 PASS。Android Gradle/AAR/APK/ADB/Jest 未执行,仍为 `IMPLEMENTED / WAITING_ANDROID_VALIDATION`。 + +# 2026-09-11 STEP-069 Git:主实现 `148bf80fe41ba566de6c1d4b439cfe372a8a453c`(`feat: add v2 multi-plane field ingress`)已完成 scoped commit;最终独立复验确认 RN codegen、TypeScript、Linux 重链与 STEP-069 两个 Core 过滤测试 2/2 PASS。STEP-062 用户修改与历史无关文件未纳入;Android Gradle/AAR/APK/ADB/Jest 仍未执行。