From e3c36880960ddb74abeafefe5c5662e1a61b46dc Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Tue, 8 Sep 2026 23:19:29 +0800 Subject: [PATCH] docs: add step061 codex task --- ...61_Binary_UV_Field_Transport_Codex任务_v1.md | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 docs/40_任务/STEP-061_Binary_UV_Field_Transport_Codex任务_v1.md diff --git a/docs/40_任务/STEP-061_Binary_UV_Field_Transport_Codex任务_v1.md b/docs/40_任务/STEP-061_Binary_UV_Field_Transport_Codex任务_v1.md new file mode 100644 index 000000000..433a9b321 --- /dev/null +++ b/docs/40_任务/STEP-061_Binary_UV_Field_Transport_Codex任务_v1.md @@ -0,0 +1,173 @@ +# STEP-061 Binary U/V Field Transport Codex任务 v1 + +## 1. 任务状态与目标 + +- 当前正式分支:`particle/main`。 +- 本任务开始前必须确认本地 HEAD 与 `origin/particle/main` 一致。 +- STEP-060 已 `CLOSED / PASS`,当前正式进入 STEP-061。 +- 目标:打通 RN Test Host → WeatherRuntime → Android Java/JNI → RasterArraySource/Core 的正式 Binary U/V Field 提交链,并在 RN Host 中得到可验证的 Timeline / Runtime Field Window 证据。 +- 本任务只实现 STEP-061 源码与静态验证;不要执行最终 AAR 发布、Windows Maven Local、APK、ADB 或 Android 实机验收,这些由任务完成后的端到端流程执行。 + +## 2. 开工前必读 + +必须先读取并遵守: + +1. `AGENTS.md` +2. `PARTICLE_BASELINE.md` +3. `docs/00_项目规范/` 全部当前规范 +4. `docs/50_Step记录/STEP-060_RNTestHost与WeatherRuntime薄桥接_v3.md` +5. `docs/报告/STEP-060F_Android最终验收报告_v1.md` +6. `docs/40_任务/STEP-053_Windy-style_Canonical_Field与Host_MapLibre_Submission_Contract_Codex任务_v1.md` +7. `docs/50_Step记录/STEP-053_Windy-style_Canonical_Field与Host_MapLibre_Submission_Contract_v1.md` +8. `docs/报告/STEP-053_Windy-style_Field与Host_Submission_Codex完成报告_v2.md` +9. `粒子开发记录.md` 最新相关记录 +## 3. 已调查并冻结的实际基线 + +当前源码已经存在以下正式链路,禁止重复造第二套 Core ingress: + +- `WeatherRuntime.submitWindField(String metadataJson, byte[] payload)` +- `MapLibreMap.submitRasterArraySourceHostField(...)` +- `NativeMapView` / JNI `jbyteArray` +- `RasterArraySource::submitHostField(metadata, payload)` +- `LocalParticleFieldFeed::load(...)` +- `ParticleFieldDataAdapter::decode(...)` + +Canonical Field Contract 继续沿用 STEP-053,不重新定义: + +- schema:`maplibre-particle-field/v1` +- layout:`interleaved-uv` +- encoding:`float32-le` +- origin:north-west +- storage:row-major +- U:eastward m/s +- V:northward m/s +- payload byteLength 必须与 width × height × 2 × sizeof(float) 一致。 +- `generation`、`validTime` 必须非零并满足 Timeline 单调性。 + +RN Test Host 当前为 React Native `0.85.2`,`@react-native/codegen 0.85.3`,Expo `56.0.4`;当前 Codegen Spec 不提供可直接映射为 Kotlin `byte[]` 的 ArrayBuffer/Uint8Array 参数类型。Expo FileSystem `56.0.11` 已存在并支持 `File.write(string | Uint8Array)`。 +## 4. 本阶段正式 Binary Transport 设计 + +本阶段固定采用 **binary file-reference transport**: + +1. JS/TS 用 `ArrayBuffer + DataView` 或等价方式构造 canonical U/V bytes,并显式以 little-endian 写入 float32。 +2. JS/TS 用 Expo FileSystem `File.write(Uint8Array)` 把原始 bytes 写入 App 本地临时文件。 +3. TurboModule 公共调用只传递 `metadataJson + payloadFileUri/path`,不把 U/V 数组塞进 JSON。 +4. Android bridge 从本地文件引用读取原始 `byte[]`,然后调用既有 `WeatherRuntime.submitWindField(metadataJson, byte[])`。 +5. Core 仍由既有 `LocalParticleFieldFeed` / `ParticleFieldDataAdapter` 做最终 schema、维度、bounds、layout、encoding、byteLength、generation、validTime 等验证并 fail-closed。 + +该设计是正式 Binary U/V transport,不是临时编码兼容层。禁止: + +- `number[]` / `Array` 跨 RN bridge 传 U/V payload; +- 把 payload 放入 JSON; +- base64; +- hex/string 编码; +- provider/network/vendor 下载逻辑进入 MapLibre Native/Core; +- 新建第二套 RasterArray/Timeline/Field Adapter; +- 绕过 `WeatherRuntime.submitWindField(...)` 直接写 Core 内部状态。 + +本阶段不要求 JSI zero-copy;如果未来需要纯内存/zero-copy buffer transport,应另开性能 Step,不在这里叠加复杂度。 +## 5. 必做实现 + +### 5.1 RN bridge API + +在现有 `weather-runtime-bridge` 上最小扩展,不新建第二个模块: + +- 增加一个稳定的 Binary Field 提交 API,参数语义为 `metadataJson + payloadFileUri/path`。 +- 返回值必须能让 RN Host 看到 `WeatherRuntime.FieldSubmitResult` 的结构化结果名称或等价稳定字符串。 +- 可以同时增加一个最小 `clearWindFields()`/reset API,若它对重复验收和 Fast Refresh 后清空 Timeline 是必要的;必须继续调用既有 `WeatherRuntime.clearWindFields()`,不得自己管理 Timeline。 +- Kotlin 侧只负责:解析本地引用、读取原始 bytes、做必要的文件可读性/大小保护、调用 `WeatherRuntime.submitWindField()`、归一化返回值。 +- 文件读取失败必须 fail-closed,不能提交空 payload,也不能伪造成功。 + +### 5.2 RN Test Host canonical fixture + +在 Test Host 内生成确定性、很小但有效的至少两帧 canonical WIND Field: + +- T0 / T1 grid 的 width、height、bounds、layout、encoding、noData 完全兼容。 +- T1 的 `validTime` 与 `generation` 严格大于 T0。 +- payload 使用 `DataView.setFloat32(offset, value, true)` 或等价明确 little-endian 的方法写 U/V。 +- 写成原始二进制临时文件;禁止 base64 或数组 JSON。 +- metadata 必须包含 Core 当前真实 parser 要求的 schema、fieldId、fieldType、displayDomain、generation、validTime、grid、bounds、vector、payload.byteLength 等字段。 +- Host 不得计算或持有 T0/T1/MIX Runtime 状态;它只生产并提交帧,窗口选择继续由 Core 管理。 +### 5.3 正向与负向证据 + +RN Host 必须提供无需猜测的验收状态,至少包括: + +- Binary Transport:READY / ERROR; +- payload 形式:明确显示 `FILE_REF / FLOAT32_LE / INTERLEAVED_UV` 或等价语义; +- Invalid Probe:提交一个确定性非法 payload(优先 byteLength/实际 bytes 不匹配),必须得到 Core 的拒绝结果; +- T0 Submit Result:应为 `ACCEPTED_PENDING_INITIAL_WINDOW`; +- T1 Submit Result:应为 `INITIAL_WINDOW_READY`; +- Runtime Field Window:最终不再是 `TIMELINE_NOT_READY`,应能显示来自 Native/Core 的 T0/T1/MIX/generation/time 等已有 runtime window 证据。 + +负向 probe 只能验证既有 Core fail-closed,不得为了让 probe 通过去放宽 Core 校验。 + +### 5.4 依赖与工程 + +- `expo-file-system` 当前实际安装版本为 `56.0.11`;如果源码直接 import,必须把它作为 Test Host 的明确直接依赖并保持与当前 Expo 56 兼容,不升级整个 Expo/RN 栈。 +- 只修改完成本任务真正必要的 RN Test Host / bridge 文件。 +- 默认不修改 MapLibre Core;只有调查证明现有 STEP-053/057 WeatherRuntime contract 存在真实阻塞缺陷时才能做最小修正,并在完成报告中单独说明原因和影响。 +- 不进入 NavSea,不修改任何 NavSea 文件。 +## 6. 允许修改范围 + +优先允许: + +- `integration/react-native/MapLibreParticleRNTestHost/App.tsx` +- `integration/react-native/MapLibreParticleRNTestHost/package.json` +- `integration/react-native/MapLibreParticleRNTestHost/package-lock.json` +- `integration/react-native/MapLibreParticleRNTestHost/README.md` +- `integration/react-native/MapLibreParticleRNTestHost/modules/weather-runtime-bridge/src/**` +- `integration/react-native/MapLibreParticleRNTestHost/modules/weather-runtime-bridge/android/**` 中源码和必要配置;禁止提交 `build/` 产物。 +- 本任务要求的中文完成报告。 + +默认禁止: + +- provider/network/vendor/Weather Service/HTTP/download/cache/prefetch 业务代码进入 Native/Core; +- 修改 NavSea; +- 修改与 STEP-061 无关的 UI、粒子视觉参数、地图行为; +- 大范围重构 STEP-053~060 已冻结链路; +- 提交现有历史 untracked 文件、build 目录、临时日志、AAR/APK。 + +若必须超出允许范围,先停止并在完成报告中标为阻塞,不要自行扩大任务。 +## 7. 验证要求 + +Codex 完成源码后必须执行并记录: + +1. `npm run typecheck`(RN Test Host)。 +2. 当前 bridge Codegen Spec 的必要生成/静态检查;只做验证,不提交生成的 build 产物。 +3. 对修改文件执行必要的语法/静态检查。 +4. `git diff --check`。 +5. 明确检索并证明正式提交链中不存在以 `number[]`、base64、payload JSON 传输 U/V 的实现。 + +未经用户明确要求,本任务**不加入 Jest,不新增 Jest 测试,不运行 Jest**。 + +本阶段不要运行: + +- `make apackage`; +- 最终 AAR Maven publish; +- Windows Gradle APK build; +- ADB 安装或实机测试。 + +AAR 编译与端到端 Android 验收将在 Codex 源码审查通过后,于同一个 `particle-codex:step061` tmux window 中继续执行。 + +编译/Codegen 等 noisy 命令遵循全局 `$build-output-throttle`。 +## 8. 必做输出 + +完成时必须实际生成: + +1. STEP-061 所需源码修改。 +2. 必要的 Test Host README/bridge contract 说明,明确 binary file-reference transport、canonical bytes、调用链和限制。 +3. `docs/报告/STEP-061_Binary_UV_Field_Transport_Codex完成报告_v1.md`。 + +完成报告至少写明: + +- 调查后的真实实现路径; +- 修改文件清单; +- RN binary file-reference transport 如何避免 number[] / base64; +- Kotlin 如何把原始 bytes 交给 `WeatherRuntime.submitWindField()`; +- invalid probe、T0、T1、Runtime Field Window 的预期结果; +- 实际执行的静态验证及结果; +- 未执行的 AAR / Windows / Android 实机项目; +- 是否修改 Core;若修改,必须逐项说明必要性; +- `git status --short` 与当前未提交范围摘要。 + +不要 commit,不要 push。完成后停在工作区,等待 ChatGPT 通过 RDC 审查真实 diff。