docs: close STEP-066 task handoff
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
OpenAI Codex
2026-09-10 22:20:34 +08:00
parent 9a09278a28
commit 9dabb95e44
2 changed files with 322 additions and 3 deletions

View File

@@ -0,0 +1,318 @@
# STEP-066 MapLibreParticleLab V3-02 Core Contract + Scalar Snapshot/Adapter — Codex任务 v1
## 0. 任务定位
本任务承接 STEP-065 已冻结的 MapLibreParticleLab V3 架构,只实施 **Core Contract / Snapshot / Adapter 层**。
目标:把当前 Wind-only、单 U/V payload 的 `maplibre-particle-field/v1` Core 输入模型,升级为 V3 内部统一的 generic snapshot,支持:
- vector-only
- scalar-only
- scalar + vector
- shared validity
- vector semantics: `VELOCITY | DIRECTION`
- v1 vector-only 作为最薄兼容 ingress normalize 到同一套 V3 snapshot
本任务不进入 GPU、shader、Android/JNI、RN、NavSea、WeatherV2,也不做 Android 构建。
## 1. 当前基线
仓库:`/mnt/sda1/MapLibreParticleLab`
分支:`particle/main`
任务书创建时 HEAD / origin:
`d23ae2079dcfef3ce48517f734fe487207e28d23`
执行时必须重新确认 branch、HEAD、origin 和 `git status --short`。若远端已合法推进,先阅读新增提交,不得 reset、checkout 覆盖或丢弃用户修改。
当前工作区已有 STEP-062 用户修改和大量历史 untracked/build 产物,全部视为无关用户内容。禁止 `git add .`、`git add -A`、clean/reset/stash 覆盖它们。
## 2. 开工前必须阅读
必须完整阅读:
- `AGENTS.md`
- `PARTICLE_BASELINE.md`
- `docs/00_项目规范/`
- `docs/20_调查/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField现状调查_v1.md`
- `docs/30_设计/MapLibreParticleLab_V3通用ScalarVectorField运行时架构设计_v1.md`
- `docs/50_Step记录/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_v1.md`
- `docs/报告/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_Codex完成报告_v1.md`
- 当前 `field_data_adapter.*`
- 当前 `local_particle_field_feed.*`
- 当前 `raster_array_source.*` 中 host field parser / Timeline / Runtime Window 相关实现
- 与 `ParticleFieldDescriptor`、`ParticleFieldSnapshot`、`ParticleFieldTimeWindow`、`sameFieldGpuContent`、`fieldIdentityChanged` 直接相关的所有调用点
- 现有相关 C++ tests/fixtures
不得根据 STEP-065 文档示例直接猜当前源码。
## 3. 冻结架构,禁止重新讨论
STEP-065 已冻结以下方向,本任务必须按此实现,不重新发明第二套模型:
1. 新 canonical schema:`maplibre-particle-field/v2`。
2. 一个 Snapshot:0/1 scalar + 0/1 vector + 1 shared validity。
3. scalar-only、vector-only、scalar+vector 合法;neither 非法。
4. vector 为 `float32-le / interleaved-uv`,U eastward、V northward。
5. scalar 为 `float32-le` 单 plane。
6. validity 为显式 shared logical validity;V3 Core 内统一为 `std::vector<uint8_t>` 或现有等价表示。
7. `VectorSemantics = VELOCITY | DIRECTION`,只在 vector present 时合法。
8. `fieldType` / `displayDomain` 不再作为 Core capability 或 validity 判断依据。
9. Renderer 的 `FieldValueSource` 属于后续 V3-03,不在本任务实现。
10. Timeline / T0-T1 / MIX / Pause / rollover ownership 不重构。
## 4. 本任务必须形成的 Core 模型
优先扩展现有 `ParticleFieldDescriptor` / `ParticleFieldSnapshot`,不要创建 `GenericWeatherField`、`RainField`、`WaveField` 等平行模型。
目标语义至少包含:
```text
ParticleFieldSnapshot
common identity/grid/time
scalar? : width*height float
vector? : width*height*2 float interleaved UV
valid : width*height uint8 shared validity
vectorSemantics? : VELOCITY | DIRECTION
```
字段命名可结合现有代码做最小调整,但必须 generic,不出现 Wind/Rain/Wave/Tide 业务枚举。
## 5. v2 Descriptor / Plane Bundle
本任务需要在 Core 层定义明确的 v2 descriptor 和 decode 输入形态。
推荐采用独立 plane bundle,而不是把三种数据重新塞回一个 ambiguous `std::vector<char>`:
```text
ParticleFieldPayloadBundle
scalar? bytes
vector? bytes
validity? bytes
```
具体 C++ 类型可根据当前接口选择 `std::optional<std::vector<char>>`、span/view 或等价简单结构,但不能引入大型新抽象。
必须保证:
- vector plane expected bytes = `cells * 2 * sizeof(float)`
- scalar plane expected bytes = `cells * sizeof(float)`
- validity plane expected bytes = `cells`(uint8)
- descriptor 声明的 channel presence 与实际 payload presence 一致
- 所有 float 必须 finite,除明确 noData 策略外不得接受 NaN/Inf
- shared validity 为 0 的 cell 可以允许 payload 内存在 finite placeholder/noData;validity=1 的 cell 对 present channel 必须是有效 finite 数据
- 不允许 neither
- DIRECTION 但无 vector 必须 reject
- vector present 但缺 vector semantics 必须 reject(除 v1 normalize)
## 6. v1 最薄兼容 ingress
现有 `maplibre-particle-field/v1` 必须继续可读,但不要维护第二套 Runtime。
v1 只支持现有 vector-only:
- `interleaved-uv`
- `float32-le`
- validity 从当前 U/V noData 规则派生
- normalize 后:`vector present`、`scalar absent`、`VectorSemantics::VELOCITY`
兼容层应该尽量放在 parser/adapter ingress,进入 Timeline 前就成为与 v2 相同的统一 snapshot。
不得给 v1 增加 scalar 字段、不得重新定义 v1 payload。
## 7. Identity / compatibility / hashing
必须重新审查并调整:
- `ParticleFieldSnapshot::isValid()`
- `isTimeInterpolationCompatibleWith()`
- `fieldIdentityChanged()`
- `sameFieldGpuContent()`
要求:
### isValid
不再硬编码 `fieldType == WIND` / `displayDomain == GLOBAL`。
必须验证至少:identity、generation、validTime、grid/bounds、channel presence、plane sizes、shared validity size、vector semantics 与 channel presence 的一致性。
### Timeline compatibility
T0/T1 必须至少保持:
- width/height 相同
- bounds 相同
- scalar presence 相同
- vector presence 相同
- vector semantics 相同
- plane encoding/layout 兼容
不得允许 scalar-only 与 vector-only 被当成同一 interpolation window。
### GPU content identity
虽然本任务不改 GPU,但 `sameFieldGpuContent()` 必须能够在未来正确区分 scalar/vector/validity 内容变化。
如果当前单 `fieldSha256` 已无法无歧义表示多 plane,应在 Core contract 中明确设计并实现最小 content identity,例如 per-plane hash 或一个明确的 aggregate hash。不得靠 fieldId/dataVersion 猜内容相同。
## 8. RasterArraySource host parser 范围
本任务只允许修改 host metadata/parser 到能够构造 v1/v2 Core descriptor/plane bundle 的程度。
若当前 `RasterArraySource::submitHostField(metadataText, payload)` 是唯一入口,允许在 C++ 层增加一个 **Core-only v2 overload / typed internal entry**,用于 tests/fixtures 直接提交 plane bundle。
但本任务禁止:
- 修改 Java/Kotlin API
- 修改 JNI signature
- 修改 RN API
- 修改已发布 `.2` package
因此 Android/RN 仍只能走现有 v1 入口是允许的;v2 正式跨 JNI ingress 留到 V3-05。
## 9. Local fixture / feed
若 `local_particle_field_feed` 或现有 C++ fixture 是最合适的验证入口,可做最小扩展以生成:
1. v1 vector-only fixture
2. v2 vector-only fixture
3. v2 scalar-only fixture
4. v2 scalar+vector fixture
5. invalid/neither fixture
6. channel mismatch fixture
Fixture 只用于 Core contract 验证,不做 GPU 可视化。
## 10. 必做验证
不加入 Jest。
必须使用现有 C++ 测试体系或最小精确 executable/test,至少验证:
- v1 Wind-style vector-only decode PASS,并 normalize 为 VELOCITY vector
- v2 vector-only PASS
- v2 scalar-only PASS
- v2 scalar+vector PASS
- neither REJECT
- scalar byteLength mismatch REJECT
- vector byteLength mismatch REJECT
- validity byteLength mismatch REJECT
- missing vector semantics REJECT
- DIRECTION without vector REJECT
- NaN/Inf in valid cell REJECT
- invalid cell 可按冻结策略安全接受 finite noData/placeholder
- T0/T1 compatible:same channel shape/semantics PASS
- scalar-only vs vector-only incompatible
- VELOCITY vs DIRECTION incompatible
- changed scalar/vector/validity content 不会被 `sameFieldGpuContent()` 误判为相同
执行规定的精确编译/测试,编译输出遵循全局 `$build-output-throttle`。
不得执行 Android Gradle、AAR、APK、ADB。
## 11. 回归保护线
本任务不得破坏:
- 当前 v1 canonical Wind fixture parser
- Source-owned Timeline
- Runtime Field Window
- T0/T1/MIX
- Pause semantics
- OLD_T1→NEW_T0 reuse 的现有决策逻辑
- normal rollover 时 `simulationRebuild=false / trailCleared=false` 的架构条件
- WeatherColorLayer / RasterParticleLayer 分离
本任务不要求 renderer 能消费 scalar;在 V3-03 前 scalar snapshot 进入 renderer 应保持 fail-closed/unavailable,而不是伪造成 U/V。
## 12. 禁止事项
不得:
- 修改 shader 或 shader generator
- 修改 `render_weather_color_layer.cpp` / `render_particle_validation_layer.cpp` 的渲染语义,除非纯编译适配且不改变行为;若确需适配必须在报告逐项列出
- 增加 FieldValueSource
- 实现 DIRECTION particle movement
- 增加 Wave physics
- 修改 Android/JNI/Java/Kotlin
- 修改 RN package/API/version
- 修改 Test Host JS/TS
- 修改 WeatherV2 / NavSea
- 解析 NSFT/PMTiles
- 新增 provider/network/cache
- 设计 N scalar/N vector channel framework
- 做 JSI/zero-copy 重构
- 执行 Jest
- 执行 Android build/install/ADB
## 13. 文档输出
必须新增/更新:
- `docs/50_Step记录/STEP-066_MapLibreParticleLab_V3-02_CoreContract与ScalarSnapshotAdapter_v1.md`
- `docs/报告/STEP-066_MapLibreParticleLab_V3-02_CoreContract与ScalarSnapshotAdapter_Codex完成报告_v1.md`
- 追加 `粒子开发记录.md`
若实施中对 STEP-065 冻结设计产生必要的小修正,必须更新 `docs/30_设计/MapLibreParticleLab_V3通用ScalarVectorField运行时架构设计_v1.md` 并明确原因;禁止静默改变设计。
所有文档使用中文。
## 14. 必做清单
结束前逐项报告“已完成 / 未完成 / 无法验证”:
- [ ] 阅读规范、STEP-065 与当前实际源码
- [ ] 确认 branch/HEAD/origin/dirty worktree
- [ ] 定义 V3 Core generic snapshot/descriptor/payload bundle
- [ ] 去除 Core validity 中 WIND/GLOBAL capability hardcode
- [ ] 实现 v2 vector-only
- [ ] 实现 v2 scalar-only
- [ ] 实现 v2 scalar+vector
- [ ] 实现 shared validity
- [ ] 实现 VectorSemantics contract
- [ ] 实现 v1 vector-only thin normalize
- [ ] 调整 interpolation compatibility
- [ ] 调整 content identity / sameFieldGpuContent
- [ ] 保持 Timeline/Runtime Window ownership 不变
- [ ] 加入最小 Core fixtures/tests
- [ ] 完成精确 Linux/Core 编译/测试
- [ ] `git diff --check` PASS
- [ ] 确认无 Android/JNI/RN/WeatherV2/NavSea 修改
- [ ] 生成 Step、完成报告、追加开发记录
不得静默跳过。
## 15. Git 收尾
完成本任务规定修改与文档后,只提交本任务相关文件到当前 `particle/main` 并 push `origin/particle/main`。
禁止提交现有 STEP-062 用户修改、历史 untracked、build/cache/android/tgz。
必须使用显式文件列表 `git add -- <files...>`,禁止 `git add .` / `-A`。
完成报告必须记录:
- source/function commit hash 与 message
- docs handoff commit(如有)
- push 结果
- 最终 `HEAD`
- 最终 `origin/particle/main`
- 未完成/无法验证项
push 失败不得声称完成。
## 16. 完成门槛
STEP-066 只有同时满足以下条件才可 CLOSED / PASS:
1. v1 vector-only 继续可 decode,并 normalize 到统一 V3 snapshot;
2. v2 vector-only/scalar-only/scalar+vector 三种组合全部 Core 验证通过;
3. neither、尺寸/semantic/finite/validity 错误全部 fail-closed;
4. Timeline compatibility 已按 channel presence + vector semantics 收紧;
5. content identity 不会把 plane 内容变化误判为 GPU same-content;
6. 未改 GPU 渲染语义、Android/JNI/RN、WeatherV2/NavSea;
7. 精确 Linux/Core 编译/测试与 `git diff --check` 通过;
8. Step/报告/开发记录完成;
9. scoped commit 成功 push 到 `origin/particle/main`。
下一步仅在 STEP-066 CLOSED / PASS 后进入 V3-03:Scalar GPU Texture + Generic Field Renderer。

View File

@@ -33,6 +33,7 @@ Linux OpenGL `mbgl-test`、受影响 `source.test.cpp.o`、`mbgl-test-runner`
## Git 收尾
- Source/function commits:`379c9ed0e`(`core: add scalar vector field snapshots`)与 `6d1f3e051`(`core: preserve fixture times in generic snapshots`)。
- Docs handoff commit:`b366a2d16`,`docs: record STEP-066 core contract`。
- Push:成功,`particle/main -> origin/particle/main`(`d23ae2079..b366a2d16`)。
- Push 后复核:`HEAD == origin/particle/main == b366a2d16170957937505e6ce05da541650dc20d`。
- Docs commits:`b366a2d16`(`docs: record STEP-066 core contract`)与 `9a09278a2`(`docs: record STEP-066 push handoff`)。
- 已完成 handoff commit:`9a09278a28170446fd3e180ae5f7c2d8d558972d`。
- 已完成 push:`particle/main -> origin/particle/main`,先后为 `d23ae2079..b366a2d16`、`b366a2d16..9a09278a2`;当时复核 `HEAD == origin/particle/main == 9a09278a28170446fd3e180ae5f7c2d8d558972d`。
- 本次仅补纳遗留任务书与本报告 Git 收尾回填;其 scoped commit/push 后最终 HEAD 以本次收尾回执为准。