test: add STEP-119 RCRR boundary variants and audit
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
@@ -55,3 +55,12 @@ Mac Metal原生CMake配置首次因PATH找不到cmake而失败,改用既有/us
|
|||||||
本轮源码锁 3d989a00a822989339a6d7cb4d23acc04396670e、APK SHA 57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135,Mac标准Android OpenGL x86_64 APK真编译/链接/打包PASS;FZG1-2安装SHA一致、preflight PASS。新STATIC_RC_NO_TIDE 90.010秒:Native64/R[0,62),missingSourceIds=[],Cache Build=1 / Reuse=3276(累计)、FastDelta=1819 / FullDelta=0、24Gate mismatch=0。原STATIC_RC 90.010秒:原Native65/R[0,63),missingSourceIds=[tide],Build=0、Reuse=0、FastDelta=0、FullDelta=305,fail-closed仍正常。新13项GTest运行/Metal/iOS/动态源变更与像素对比均未完成,保持ANDROID_FAST_CORE_PASS/OVERALL_PARTIAL。详细原始数据和sha见 docs/60_测试/STEP-119_FZG1_原PBF真实Fast验收结果_20261011.md。
|
本轮源码锁 3d989a00a822989339a6d7cb4d23acc04396670e、APK SHA 57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135,Mac标准Android OpenGL x86_64 APK真编译/链接/打包PASS;FZG1-2安装SHA一致、preflight PASS。新STATIC_RC_NO_TIDE 90.010秒:Native64/R[0,62),missingSourceIds=[],Cache Build=1 / Reuse=3276(累计)、FastDelta=1819 / FullDelta=0、24Gate mismatch=0。原STATIC_RC 90.010秒:原Native65/R[0,63),missingSourceIds=[tide],Build=0、Reuse=0、FastDelta=0、FullDelta=305,fail-closed仍正常。新13项GTest运行/Metal/iOS/动态源变更与像素对比均未完成,保持ANDROID_FAST_CORE_PASS/OVERALL_PARTIAL。详细原始数据和sha见 docs/60_测试/STEP-119_FZG1_原PBF真实Fast验收结果_20261011.md。
|
||||||
|
|
||||||
- 2026-10-11 STEP119实机首次FAST_OBSERVED:APK源3d989a00a822989339a6d7cb4d23acc04396670e SHA=57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135,FZG1-2安装/preflight PASS;STATIC_RC_NO_TIDE 90秒 FastDelta1819/FullDelta0、R Build1/Reuse3276、24Gate mismatch0、Native64,missingSourceIds=[]。仅正向目标首次通过,负例/视觉/GTest/iOS未验,STEP119 PARTIAL。详见 docs/报告/STEP-119_Android真机Fast首次通过_阶段验收_v1.md。
|
- 2026-10-11 STEP119实机首次FAST_OBSERVED:APK源3d989a00a822989339a6d7cb4d23acc04396670e SHA=57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135,FZG1-2安装/preflight PASS;STATIC_RC_NO_TIDE 90秒 FastDelta1819/FullDelta0、R Build1/Reuse3276、24Gate mismatch0、Native64,missingSourceIds=[]。仅正向目标首次通过,负例/视觉/GTest/iOS未验,STEP119 PARTIAL。详见 docs/报告/STEP-119_Android真机Fast首次通过_阶段验收_v1.md。
|
||||||
|
|
||||||
|
## RDC STEP-119 RCRR 多配置续验(2026-10-11 JST)
|
||||||
|
|
||||||
|
- Integration origin/main 经 RDC 同步核验为 `80667d6c343411d03a760425438e3d292f452118`;Particle 起点 `46c88b0209474376225b54ae0ad701881673743d`,仍在 `particle/main`;两份 STEP110/111 未跟踪任务文档未触碰。
|
||||||
|
- 同一已安装 APK 源 `3d989a00a822989339a6d7cb4d23acc04396670e`,SHA `57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135`,真机原 `PARTIAL_RCRR` 80秒:R0 Build0/Reuse0/missing tide;R2/R3 各 Build1/Reuse536;FastDelta0/FullDelta596、decisionMismatch0。即局部复用有效、全帧 Fast 安全拒绝。
|
||||||
|
- 真机导出原63层 `styleParity.baseLayerManifest` 确认 tide=2、sea=3、clip-outline=31、special=37;天气实际在原宽 C 中,不在 R0。由此修正早期错误的分段位置推测。
|
||||||
|
- Test App 增加三种 `RCRR_*_NO_TIDE` 场景,分别测试窄 C、宽 C 与错误动态 R;基于上述真实 Manifest 校准成 Native64 精确 R/C 区间,未修改正式 PBF/原场景/24 Gate。验证器精确验三段 R 边界;4项 Python unittest PASS、Style Manifest 静态索引核对 PASS、git diff --check PASS。
|
||||||
|
- **尚未完成**:新 Kotlin Test App 的用户手工 APK 编译及三场景真机 90秒回归、图像目视、Camera/Source/Style/Tile/Annotation/Context 真机失效和恢复、STEP119 13项 GTest 真跑、Metal/iOS。Mac 原有 libuv 缺失限制保持,不擅自安装或升级工具链。STEP-119 **PARTIAL,不 CLOSED**。
|
||||||
|
- 文档:`docs/60_测试/STEP-119_RCRR多配置验收矩阵_v1.md`、`docs/报告/STEP-119_RCRR多场景局限性_阶段验收_v1.md`。原始真机记录位于 ignored `artifacts/maplibre-particle/android-validation/step119-rcrr-observe-20261011_172720/partial_rcrr/`。
|
||||||
|
|||||||
68
docs/60_测试/STEP-119_RCRR多配置验收矩阵_v1.md
Normal file
68
docs/60_测试/STEP-119_RCRR多配置验收矩阵_v1.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# STEP-119 RCRR 多配置实机与验证矩阵 v1
|
||||||
|
|
||||||
|
日期:2026-10-11(JST)。执行入口:Mac.lan RDC,Particle `particle/main`。状态:**一组真机完成;三组新配置已实现、静态核对通过但未构建/上机**。非最终验收。
|
||||||
|
|
||||||
|
## 1. 场景与边界
|
||||||
|
|
||||||
|
本轮沿用 STEP-119 源码 APK(commit `3d989a00a822989339a6d7cb4d23acc04396670e`,SHA-256 `57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135`),不重复已通过的 Android 原生完整编译。设备 `192.168.200.139:5555`,x86_64。当前远端 HEAD 起点为 `46c88b0209474376225b54ae0ad701881673743d`,其与 APK commit 的后续差异为已有报告/Step 文档,而非新 Android 源码。
|
||||||
|
|
||||||
|
不改正式 PBF/Sprite/Glyph、Source 接口、Shared Core、24 Gate、发布版本,不清理 STEP-110/111 两份未跟踪任务书。保留原 `PARTIAL_RCRR`、原 `STATIC_RC` 与 `STATIC_RC_NO_TIDE`,后续新场景只在测试副本中排除唯一 `tide-spots→tide` 孤立 Symbol 层,并恢复空 Annotation 辅助层的正常生命周期。
|
||||||
|
|
||||||
|
## 2. 已执行:原 PARTIAL_RCRR
|
||||||
|
|
||||||
|
- 80.007 秒实机,PID `28169`,完整摘要 3 份,同源 APK/设备 SHA 一致。
|
||||||
|
- 原始 Native 图层 66,原 63 PBF + 2 天气 + 1 SDK Annotation;R[0,3)、C[3,39)、R[39,64)、R[64,66)。
|
||||||
|
- R0:Build 0、Reuse 0、Fallback 595、missingSourceIds=[tide];R2:Build 1、Reuse 536;R3:Build 1、Reuse 536。
|
||||||
|
- 观测区间:FastDelta=0、FullDelta=596,最后 120 帧 Full=119、Fast=0,decisionMismatch=0。
|
||||||
|
- Native 24 Gate 累计 `unsupported-continuous-layer=599`、`unsupported-scene=599`、`cache-invalid=595`;这些是场景累计,**不是**对应原因的独立帧数。
|
||||||
|
- 结论:**全帧 Fast 安全拒绝通过;局部 R2/R3 的 Build/Reuse 已实际观察到**。这不构成 RCRR 加速性能通过。
|
||||||
|
|
||||||
|
原证据:
|
||||||
|
`artifacts/maplibre-particle/android-validation/step119-rcrr-observe-20261011_172720/partial_rcrr/result.json`,同目录有 `logcat.txt` 与 `screen.png`。
|
||||||
|
|
||||||
|
## 3. 基于真实设备 Style Manifest 校准分段
|
||||||
|
|
||||||
|
从设备 `run-as` 只读提取的 `step113-STATIC_RC-324220201.json`,包含当前实际 63 层 `baseLayerManifest`;其 PBF 指纹 `e0f9c2d1df38ae5d5953b561c52efe2f8590336de80b988e1d2935580d30b996` 与已通过 Fast 的场景一致。
|
||||||
|
|
||||||
|
原基础层:background=0、base-raster=1、tide-spots=2、sea-area-fill=3、clip-outline=31、special-pattern-line-754=37、最后的 place-labels-land-ja=62。天气插在 clip-outline **之后**。因此原 R0 是前三层(包括 tide),天气并未落入 R0;原 C1 是宽 C,包含天气与普通静态 PBF 层。禁止再用此前错误的“天气在 R0”解释原负例。
|
||||||
|
|
||||||
|
新增 Test App 变体(全部保留其余 62 原图层、天气数据与顺序;移除 SDK 空 Annotation 辅助层;Native 总层数预期 64):
|
||||||
|
|
||||||
|
| 场景 | 期望 R/C 索引 | 主要目标 |
|
||||||
|
|---|---|---|
|
||||||
|
| `RCRR_C_NARROW_NO_TIDE` | R[0,31)、C[31,33)、R[33,63)、R[63,64) | C 仅含 WeatherColor/Particle;检验所有 R 缓存与整帧 Fast 能否真实通过 |
|
||||||
|
| `RCRR_C_WIDE_NO_TIDE` | R[0,2)、C[2,38)、R[38,63)、R[63,64) | C 混入普通 PBF;验证不支持的连续图层是否安全拒绝整帧 Fast |
|
||||||
|
| `RCRR_R_DYNAMIC_NO_TIDE` | R[0,33)、C[33,38)、R[38,63)、R[63,64) | 故意将动态天气放入 R;检验版本/连续输入不允许错误静态复用 |
|
||||||
|
|
||||||
|
源级校准证据:
|
||||||
|
`artifacts/maplibre-particle/android-validation/step119_rcrr_style_structure.json`。该结果是**实际设备导出数据上的静态切分核对,不是新 APK GPU 验证**。Mac 通过 Python 直接 GET 正式 Style 曾收到 HTTP 403,因此优先复用了相同 Style 指纹的设备导出 Manifest;没有修改服务器资源。
|
||||||
|
|
||||||
|
## 4. 静态测试与当前缺口
|
||||||
|
|
||||||
|
新增 `tools/particle_android_validation/test_step119_rcrr_scenarios.py`,四项 Python unittest 全部 PASS:三种索引互相排斥、缺 tide/缺 Annotation 清理不得通过、范围尾部和段数不对必须拒绝、原 STATIC_RC_NO_TIDE 不回退为错误结构。验证器 `scene_parity_valid` 对 64 层 RCRR 三 R 段改用精确区间校验;原 63 层判断、90 秒观察、24 Gate 和 Fast 判据不放宽。`git diff --check` PASS。
|
||||||
|
|
||||||
|
**没有对新 Kotlin 场景做 Android 编译/安装**(遵守用户手工 Android 编译及本轮不重复已有完整编译限制)。新增三场景的 Kotlin 可编译性与 Native 真机结果必须记 `NOT VERIFIED`。新增 13 项 STEP-119 GTest 仍未运行;Mac Metal CMake 被既有 libuv 缺失阻塞,本轮不安装或升级工具链;iOS Metal/实体机亦未验证。
|
||||||
|
|
||||||
|
## 5. 下次同一次人工 APK 构建后的串行设备验收
|
||||||
|
|
||||||
|
源码 scoped commit/push 完成后,由用户按已有标准在 Mac 手工构建**新 HEAD** 的 x86_64 Android OpenGL Test APK,不得使用旧 `3d989a` APK冒充新场景;验证 build-info commit、APK SHA、设备 base.apk SHA 一致后,逐一运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/tei/dev/MapLibreParticleLab
|
||||||
|
./tools/particle_android_validation/build_validation_apk.sh
|
||||||
|
adb -s 192.168.200.139:5555 install -r artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk
|
||||||
|
python3 -B tools/particle_android_validation/verify_step113_fast_path.py --serial 192.168.200.139:5555 --preflight-only
|
||||||
|
python3 -B tools/particle_android_validation/verify_step113_fast_path.py --serial 192.168.200.139:5555 --scenario RCRR_C_NARROW_NO_TIDE --seconds 90
|
||||||
|
python3 -B tools/particle_android_validation/verify_step113_fast_path.py --serial 192.168.200.139:5555 --scenario RCRR_C_WIDE_NO_TIDE --seconds 90
|
||||||
|
python3 -B tools/particle_android_validation/verify_step113_fast_path.py --serial 192.168.200.139:5555 --scenario RCRR_R_DYNAMIC_NO_TIDE --seconds 90
|
||||||
|
```
|
||||||
|
|
||||||
|
每步独立读取退出码与 result.json:完整 R/C、Source/Tile、R0/R2/R3 Build/Reuse/Invalidate、Fast/Full 差分、24 Gate、120 帧、生命周期/判定一致性。正向窄 C 必须先 Full 建立证书,再 Build 和成功 Reuse 后 Fast;若失败记录真实 gate,而不是降阈值。宽 C 和动态 R 是安全负例,`NO_FAST_OBSERVED/exit2` 若符合完整原因和分段预期属于负例通过,而非直接整体失败。禁止直接用这些负例宣称 Fast 不可用。
|
||||||
|
|
||||||
|
之后须补:静止视觉 Full/RCRR 同资源同视角人工航标、文字、Symbol、层序对照;Camera/Source/Style/Tile/Annotation/Context/cache toggle 的瞬时失效、Full 回退、重新稳定后的 Build/Reuse;13 GTest 真实执行和 Mac Metal/iOS 独立验证。视觉比对时动态粒子会造成像素差异,不能简单拿整屏逐像素一致作为静态 Symbol 结论。
|
||||||
|
|
||||||
|
## 6. 当前判定
|
||||||
|
|
||||||
|
`ANDROID_RCRR_FAIL_CLOSED_OBSERVED / NEW_VARIANTS_SOURCE_READY / STEP119_PARTIAL`。
|
||||||
|
|
||||||
|
主要已确认局限:多 R 缓存复用并不代表全帧 Fast;含缺源 R 会阻断、过宽 C 中非支持类型的连续层触发拒绝;未实测新窄 C 前,不能推断 RCRR 性能收益。待验证风险:多 RenderTarget/Composite 成本、全局 Symbol Placement/Atlas 证书联动、局部更新导致跨 R 全局失效、上层标记/文字的层序与图像等价、iOS/Metal 一致性。
|
||||||
64
docs/报告/STEP-119_RCRR多场景局限性_阶段验收_v1.md
Normal file
64
docs/报告/STEP-119_RCRR多场景局限性_阶段验收_v1.md
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# STEP-119 RCRR 多场景局限性阶段验收报告 v1
|
||||||
|
|
||||||
|
日期:2026-10-11 JST
|
||||||
|
|
||||||
|
## 一、目标与结论
|
||||||
|
|
||||||
|
**结论:部分可行/阶段 PARTIAL。** Android 真机已证明一个原始四段 RCRR 场景能让后两段 R 分别 Build=1、Reuse=536;但最前 R 缺失 `tide`,同时宽 C 不满足当前 Fast 场景约束,整帧持续 Full。已新增三种区分 C 宽度及错误动态 R 的 Test App 对照入口,并据设备真实 Style 63 层清单完成静态区间核对。新增入口仍需用户手工编译 APK 后实测,不能宣称三种 GPU 场景 PASS;STEP-119 不 CLOSED。
|
||||||
|
|
||||||
|
## 二、实际基线和执行链
|
||||||
|
|
||||||
|
- RDC 设备:Mac.lan;Mac 仓库 `/Users/tei/dev/MapLibreParticleLab`,当前分支 `particle/main`,本轮起点 HEAD `46c88b0209474376225b54ae0ad701881673743d`。
|
||||||
|
- Integration `main` 已通过 RDC `git fetch` + `git merge --ff-only`,本地/远端一致 `80667d6c343411d03a760425438e3d292f452118`;已读取 `PARTICLE_PROJECT_INSTRUCTIONS.md`、README、WORKFLOW、TEAM_MODEL、contracts/rfc/adr/status/compatibility、项目 AGENTS/规范/总则。
|
||||||
|
- APK 源码锁:`3d989a00a822989339a6d7cb4d23acc04396670e`,SHA-256:`57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135`,ADB:`192.168.200.139:5555`。此次没有重复 Android 编译/安装。源 HEAD 与已安装 APK 的差异由先前文档提交构成;新测试源码改动后,后续新场景须重新进行用户手工 APK 构建、SHA 锁定。
|
||||||
|
- 既有 `STATIC_RC_NO_TIDE` 正向 FastDelta=1819、FullDelta=0、Build=1、Reuse=3276 和原 `STATIC_RC` 63 层缺源负向 Fast=0/Full=305,均为已验收历史证据,没有重复执行。
|
||||||
|
|
||||||
|
## 三、已执行真机 RCRR 和证据
|
||||||
|
|
||||||
|
`PARTIAL_RCRR` 原场景运行 80.007 秒、PID=28169,3 个完整 Native 摘要,设备 SHA 一致。Native 总数 66;R[0,3) / C[3,39) / R[39,64) / R[64,66)。
|
||||||
|
|
||||||
|
| 指标 | 实际结果 |
|
||||||
|
|---|---|
|
||||||
|
| R0 | Build=0 / Reuse=0 / missingSourceIds=[tide] |
|
||||||
|
| R2 | Build=1 / Reuse=536 |
|
||||||
|
| R3 | Build=1 / Reuse=536 |
|
||||||
|
| 80 秒增量 | Fast=0 / Full=596 |
|
||||||
|
| 最近 120 帧 | Fast=0 / Full=119 |
|
||||||
|
| decisionMismatch | 0 |
|
||||||
|
| 24 Gate 累计 | unsupported-continuous-layer=599、unsupported-scene=599、cache-invalid=595 |
|
||||||
|
|
||||||
|
执行进程退出码 0,表示**原生观测及取证成功**,不表示 RCRR Fast 成功。证据路径:
|
||||||
|
`artifacts/maplibre-particle/android-validation/step119-rcrr-observe-20261011_172720/partial_rcrr/result.json`、`logcat.txt`、`screen.png`。
|
||||||
|
|
||||||
|
### 关键事实校正
|
||||||
|
|
||||||
|
从设备 Debug App 的 `step113-STATIC_RC-324220201.json` 只读提取 `styleParity.baseLayerManifest`,正式 63 层索引:`tide-spots=2`、`sea-area-fill=3`、`clip-outline=31`、`special-pattern-line-754=37`。其生产 Style 指纹与当日 Fast 成功场景一致。原 R0 只有 background / base-raster / tide-spots;**天气在 C 内而不是 R0**。原 C 范围很宽,混合了普通海图图层和天气动态层。此前对 R0 图层组成的初步猜测已经被真实 Manifest 修正,未写入最终推荐结论。
|
||||||
|
|
||||||
|
## 四、新增三种 RCRR Test App 入口(未上机)
|
||||||
|
|
||||||
|
- `RCRR_C_NARROW_NO_TIDE`:R[0,31) / C[31,33) / R[33,63) / R[63,64),C 只包含两天气层。用于验证全段缓存和最终 Fast 的可能性。
|
||||||
|
- `RCRR_C_WIDE_NO_TIDE`:R[0,2) / C[2,38) / R[38,63) / R[63,64),C 混合天气与静态 PBF。用于验证白名单边界和宽 C 的实际代价。
|
||||||
|
- `RCRR_R_DYNAMIC_NO_TIDE`:R[0,33) / C[33,38) / R[38,63) / R[63,64),天气被放入错误 R。用于验证失效与 Full 安全拒绝。
|
||||||
|
|
||||||
|
代码变更严格局限于 Test App `Step113PbfGateScene.kt`、`verify_step113_fast_path.py` 和新增 `test_step119_rcrr_scenarios.py`,保留原所有场景。生产 PBF63 的定义、服务器 URL、天气实际字段及图层相对顺序不变;只在明确 NO_TIDE 测试副本排除已确认的唯一孤立层。对新场景增加精确 R 范围匹配,不降低原验证器 24 Gate 或 FAST_OBSERVED 条件。
|
||||||
|
|
||||||
|
源级校验:设备实际 Manifest 分段结构 3/3 与预期一致;Python unittest 4/4 PASS;`git diff --check` PASS。没有 Android Kotlin/NDK 编译或新 APK/设备验收,**三种新增场景为 SOURCE_READY / NOT VERIFIED**。
|
||||||
|
|
||||||
|
## 五、当前 RCRR 模式的局限性
|
||||||
|
|
||||||
|
1. **全帧 Fast 是全局准入。** R2/R3 的 Cache 能各自 Build/Reuse,但 R0 缺源时整帧仍 Full;不能按各 R Reuse 求和冒充 Fast。
|
||||||
|
2. **连续 C 不是任意图层的免责通道。** 原宽 C 下 `unsupported-continuous-layer` 持续增加,说明当前 Fast 路径不支持直接把大量普通海图层划入 C 并期望跳过完整场景处理。需要以新窄 C 实测来确认适用边界。
|
||||||
|
3. **配置高度依赖真实 Style 顺序。** 同一个 layerId 相对位置设错可能造成循环 C 混入静态层或天气落入 R;实际 PBF 63 层与 NavSea 113 层现场定义不同,不能按历史索引照搬。
|
||||||
|
4. **缓存分段独立性有限。** 即使 R 分段有缓存,Source/Style/Tile/Symbol Placement/Atlas/Opacity/Annotation 的全局结果版本可能要求跨段失效;当前 13 项源级 C++ 测试尚未真正 GTest 运行,相关安全边界待进一步真机验证。
|
||||||
|
5. **性能与显存不是必然收益。** 多个 R RenderTarget/Composite 会增大缓存资源与混合成本;当前没有同场景 RC/RCRR 同相机有效帧时间和 GPU 内存对照,不能声称多段比单 R 更快。
|
||||||
|
6. **视觉与平台仍未关闭。** 尚无强制 Full/RCRR 同 Style 静态航标、Symbol、文字、层序的人工确认;Metal CMake 仍因既有 libuv 缺失未配置成功,13 GTest 与 iOS 真机没有新验证。
|
||||||
|
|
||||||
|
## 六、风险与下一步
|
||||||
|
|
||||||
|
建议以**窄 C、其余静态 R**作为 RCRR 正向候选,保留原 63 层 RCRR 和两个新负向变体。下一次由用户按既有 Mac 标准手工只进行一轮最新源码 APK 构建后,RDC 串行执行三场景各 90 秒真实诊断和同视角视觉对照;若窄 C 仍被 unsupported gate 拒绝,应保留 Full、检查准确原因和局限边界,而不是修改 Gate 放行。
|
||||||
|
|
||||||
|
状态为 `ANDROID_RCRR_FAIL_CLOSED_OBSERVED / MULTI_RCRR_SOURCE_READY / OVERALL_PARTIAL`。更详细命令、矩阵和预期证据位于 `docs/60_测试/STEP-119_RCRR多配置验收矩阵_v1.md`。本次不是 GSRL 正式发行,没有 SOURCE_LOCK、发布 Tag 或版本覆盖;未跟踪 STEP-110/111 文档禁止纳入提交。
|
||||||
|
|
||||||
|
## 七、Git 收尾
|
||||||
|
|
||||||
|
本段由 RDC 在完成 scoped commit/push 与远端回读后补写最终提交、Push 与远端 HEAD;在此之前不得声称 Git 收尾通过。
|
||||||
@@ -28,7 +28,8 @@ internal class Step113PbfGateScene(
|
|||||||
private val map: MapLibreMap,
|
private val map: MapLibreMap,
|
||||||
private val display: (String) -> Unit
|
private val display: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
enum class Scenario { PBF63, STATIC_RC, PARTICLE_OFF, PARTIAL_RCRR, SOURCE_CHANGE, STATIC_RC_NO_TIDE }
|
enum class Scenario { PBF63, STATIC_RC, PARTICLE_OFF, PARTIAL_RCRR, SOURCE_CHANGE, STATIC_RC_NO_TIDE,
|
||||||
|
RCRR_C_NARROW_NO_TIDE, RCRR_C_WIDE_NO_TIDE, RCRR_R_DYNAMIC_NO_TIDE }
|
||||||
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
private var generation = 0
|
private var generation = 0
|
||||||
@@ -126,7 +127,7 @@ internal class Step113PbfGateScene(
|
|||||||
// STEP-118: Keep the original 63-layer PBF baseline unchanged.
|
// STEP-118: Keep the original 63-layer PBF baseline unchanged.
|
||||||
// Only the explicitly named user-approved variant excludes one
|
// Only the explicitly named user-approved variant excludes one
|
||||||
// orphaned Symbol layer whose tide Source is already absent.
|
// orphaned Symbol layer whose tide Source is already absent.
|
||||||
val omitTideLayer = scenario == Scenario.STATIC_RC_NO_TIDE
|
val omitTideLayer = isNoTideVariant(scenario)
|
||||||
val tideDependent = (0 until base.length()).filter {
|
val tideDependent = (0 until base.length()).filter {
|
||||||
base.getJSONObject(it).optString("source") == TIDE_SOURCE
|
base.getJSONObject(it).optString("source") == TIDE_SOURCE
|
||||||
}
|
}
|
||||||
@@ -179,7 +180,7 @@ internal class Step113PbfGateScene(
|
|||||||
.put("sprite", root.optString("sprite"))
|
.put("sprite", root.optString("sprite"))
|
||||||
.put("glyphs", root.optString("glyphs")).put("vectorSource", JSONObject(source.toString()))
|
.put("glyphs", root.optString("glyphs")).put("vectorSource", JSONObject(source.toString()))
|
||||||
.put("productionSources", JSONObject(root.getJSONObject("sources").toString()))
|
.put("productionSources", JSONObject(root.getJSONObject("sources").toString()))
|
||||||
.put("internalAnnotationPolicy", "仅STATIC_RC及STATIC_RC_NO_TIDE加载时移除空SDK辅助层;后续添加不再移除")
|
.put("internalAnnotationPolicy", "STATIC_RC及全部NO_TIDE场景加载时移除空SDK辅助层;后续添加不再移除")
|
||||||
.put("styleAdjustmentScope", if (omitTideLayer)
|
.put("styleAdjustmentScope", if (omitTideLayer)
|
||||||
"TEST-APP-ONLY;原生产Style63层不变;测试副本排除唯一tide-spots→tide孤立Symbol层" else
|
"TEST-APP-ONLY;原生产Style63层不变;测试副本排除唯一tide-spots→tide孤立Symbol层" else
|
||||||
"NONE;生产Style基础63层原样")
|
"NONE;生产Style基础63层原样")
|
||||||
@@ -189,7 +190,7 @@ internal class Step113PbfGateScene(
|
|||||||
check(!sources.has(SOURCE)) { "天气 Source ID 冲突" }
|
check(!sources.has(SOURCE)) { "天气 Source ID 冲突" }
|
||||||
sources.put(SOURCE, JSONObject().put("type", "raster-array").put("host-field-submission", true))
|
sources.put(SOURCE, JSONObject().put("type", "raster-array").put("host-field-submission", true))
|
||||||
val layers = JSONArray()
|
val layers = JSONArray()
|
||||||
val prefix = scenario == Scenario.PARTIAL_RCRR
|
val prefix = isRcrrVariant(scenario)
|
||||||
for (i in 0 until effectiveBase.length()) {
|
for (i in 0 until effectiveBase.length()) {
|
||||||
layers.put(effectiveBase.getJSONObject(i))
|
layers.put(effectiveBase.getJSONObject(i))
|
||||||
if (prefix && effectiveBase.getJSONObject(i).getString("id") == "clip-outline") addFields(layers)
|
if (prefix && effectiveBase.getJSONObject(i).getString("id") == "clip-outline") addFields(layers)
|
||||||
@@ -222,16 +223,24 @@ internal class Step113PbfGateScene(
|
|||||||
.put("baseParityBasis", if (omitTideLayer)
|
.put("baseParityBasis", if (omitTideLayer)
|
||||||
"同次SDK生产Style63层回读;测试副本仅排除tide-spots,其余62层定义逐项比较;不等同原63层像素验收" else
|
"同次SDK生产Style63层回读;测试副本仅排除tide-spots,其余62层定义逐项比较;不等同原63层像素验收" else
|
||||||
"同次SDK生产Style回读;完整定义逐层比较,不是设备画面证明")
|
"同次SDK生产Style回读;完整定义逐层比较,不是设备画面证明")
|
||||||
val plan = planJson(scenario, effectiveIds.last())
|
val clipIndex = effectiveIds.indexOf("clip-outline")
|
||||||
parity.put("testPlanSelector", if (scenario == Scenario.PARTIAL_RCRR)
|
check(clipIndex >= 0 && clipIndex + 1 < effectiveIds.size) {
|
||||||
"结构RCRR:sea-area-fill/special-pattern-line-754/最后生产层ID;非现场113边界" else
|
"生产Style的clip-outline之后没有基础图层;不可推断RCRR天气位置"
|
||||||
if (hasField) "当前NavSea源码RC:rn-weather-color" else "基础63层全RETAINED")
|
}
|
||||||
|
val plan = planJson(scenario, effectiveIds.last(), effectiveIds[clipIndex + 1])
|
||||||
|
parity.put("testPlanSelector", when (scenario) {
|
||||||
|
Scenario.PARTIAL_RCRR -> "旧RCRR缺源负对照:R0包含缺源tide,C1混合天气与大量静态PBF"
|
||||||
|
Scenario.RCRR_C_NARROW_NO_TIDE -> "RCRR窄C:仅天气;两段后续静态R"
|
||||||
|
Scenario.RCRR_C_WIDE_NO_TIDE -> "RCRR宽C:天气及部分PBF;后续静态R"
|
||||||
|
Scenario.RCRR_R_DYNAMIC_NO_TIDE -> "RCRR错误动态R:天气落R0;验证安全拒绝"
|
||||||
|
else -> if (hasField) "当前NavSea源码RC:rn-weather-color" else "基础63层全RETAINED"
|
||||||
|
})
|
||||||
.put("requestedPlan", JSONObject(plan))
|
.put("requestedPlan", JSONObject(plan))
|
||||||
commandResults.put("planAccepted", map.setRenderSegmentPlan(plan))
|
commandResults.put("planAccepted", map.setRenderSegmentPlan(plan))
|
||||||
map.setStyle(Style.Builder().fromJson(root.toString())) testStyle@ { style ->
|
map.setStyle(Style.Builder().fromJson(root.toString())) testStyle@ { style ->
|
||||||
if (!running || epoch != generation) return@testStyle
|
if (!running || epoch != generation) return@testStyle
|
||||||
try {
|
try {
|
||||||
if (scenario == Scenario.STATIC_RC || scenario == Scenario.STATIC_RC_NO_TIDE) {
|
if (scenario == Scenario.STATIC_RC || isNoTideVariant(scenario)) {
|
||||||
removeEmptyAnnotationLayer(style, ids)
|
removeEmptyAnnotationLayer(style, ids)
|
||||||
}
|
}
|
||||||
map.cameraPosition = CameraPosition.Builder().target(LatLng(33.45, 129.97))
|
map.cameraPosition = CameraPosition.Builder().target(LatLng(33.45, 129.97))
|
||||||
@@ -494,13 +503,27 @@ internal class Step113PbfGateScene(
|
|||||||
private const val ANNOTATION_LAYER = "org.maplibre.annotations.points"
|
private const val ANNOTATION_LAYER = "org.maplibre.annotations.points"
|
||||||
private const val FORECAST_MS = 1786060800000L
|
private const val FORECAST_MS = 1786060800000L
|
||||||
|
|
||||||
private fun planJson(s: Scenario, finalBaseId: String): String {
|
private fun isRcrrVariant(s: Scenario): Boolean = s == Scenario.PARTIAL_RCRR ||
|
||||||
|
s == Scenario.RCRR_C_NARROW_NO_TIDE || s == Scenario.RCRR_C_WIDE_NO_TIDE ||
|
||||||
|
s == Scenario.RCRR_R_DYNAMIC_NO_TIDE
|
||||||
|
|
||||||
|
private fun isNoTideVariant(s: Scenario): Boolean = s == Scenario.STATIC_RC_NO_TIDE ||
|
||||||
|
s == Scenario.RCRR_C_NARROW_NO_TIDE || s == Scenario.RCRR_C_WIDE_NO_TIDE ||
|
||||||
|
s == Scenario.RCRR_R_DYNAMIC_NO_TIDE
|
||||||
|
|
||||||
|
private fun planJson(s: Scenario, finalBaseId: String, firstAfterClipId: String): String {
|
||||||
val segments = JSONArray().put(JSONObject().put("strategy", "RETAINED"))
|
val segments = JSONArray().put(JSONObject().put("strategy", "RETAINED"))
|
||||||
if (s != Scenario.PBF63) {
|
if (s != Scenario.PBF63) {
|
||||||
segments.put(JSONObject().put("strategy", "CONTINUOUS")
|
val continuousStart = when (s) {
|
||||||
.put("startLayerId", if (s == Scenario.PARTIAL_RCRR) "sea-area-fill" else COLOR))
|
Scenario.PARTIAL_RCRR, Scenario.RCRR_C_WIDE_NO_TIDE -> "sea-area-fill"
|
||||||
if (s == Scenario.PARTIAL_RCRR) {
|
Scenario.RCRR_R_DYNAMIC_NO_TIDE -> firstAfterClipId
|
||||||
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", "special-pattern-line-754"))
|
else -> COLOR
|
||||||
|
}
|
||||||
|
segments.put(JSONObject().put("strategy", "CONTINUOUS").put("startLayerId", continuousStart))
|
||||||
|
if (isRcrrVariant(s)) {
|
||||||
|
val upperRetainedStart = if (s == Scenario.RCRR_C_NARROW_NO_TIDE)
|
||||||
|
firstAfterClipId else "special-pattern-line-754"
|
||||||
|
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", upperRetainedStart))
|
||||||
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", finalBaseId))
|
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", finalBaseId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""STEP-119 RCRR 验证器结构契约测试;合成样本不代表真机 GTest 或 GPU PASS。"""
|
||||||
|
import importlib.util
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
MODULE = Path(__file__).with_name("verify_step113_fast_path.py")
|
||||||
|
spec = importlib.util.spec_from_file_location("step113", MODULE)
|
||||||
|
verifier = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(verifier)
|
||||||
|
|
||||||
|
|
||||||
|
def sample(retained):
|
||||||
|
return {
|
||||||
|
"planValid": True,
|
||||||
|
"basePreserved": False,
|
||||||
|
"tideLayerExcluded": True,
|
||||||
|
"originalBaseLayerCount": 63,
|
||||||
|
"effectiveBaseLayerCount": 62,
|
||||||
|
"excludedLayerId": "tide-spots",
|
||||||
|
"excludedLayerSource": "tide",
|
||||||
|
"excludedLayerCount": 1,
|
||||||
|
"actualLayers": 64,
|
||||||
|
"commands": {"emptyBuiltinAnnotationLayerRemoved": True,
|
||||||
|
"annotationSourcePreserved": True},
|
||||||
|
"sources": [{"sourceId": "navsea_delivery"},
|
||||||
|
{"sourceId": "rn-weather-fields"}],
|
||||||
|
"retained": retained,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def regions(r0_end, r2_start):
|
||||||
|
return [
|
||||||
|
{"begin": 0, "end": r0_end},
|
||||||
|
{"begin": r2_start, "end": 63},
|
||||||
|
{"begin": 63, "end": 64},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Step119RcrrVerifierTests(unittest.TestCase):
|
||||||
|
def test_three_rcrr_shapes_have_distinct_expected_boundaries(self):
|
||||||
|
shapes = {
|
||||||
|
"RCRR_C_NARROW_NO_TIDE": regions(31, 33),
|
||||||
|
"RCRR_C_WIDE_NO_TIDE": regions(2, 38),
|
||||||
|
"RCRR_R_DYNAMIC_NO_TIDE": regions(33, 38),
|
||||||
|
}
|
||||||
|
for scenario, retained in shapes.items():
|
||||||
|
with self.subTest(scenario=scenario):
|
||||||
|
self.assertTrue(verifier.scene_parity_valid(sample(retained), scenario))
|
||||||
|
for other in shapes:
|
||||||
|
if other != scenario:
|
||||||
|
self.assertFalse(verifier.scene_parity_valid(sample(retained), other))
|
||||||
|
|
||||||
|
def test_missing_source_or_annotation_policy_never_passes(self):
|
||||||
|
for scenario, retained in [
|
||||||
|
("RCRR_C_NARROW_NO_TIDE", regions(31, 33)),
|
||||||
|
("RCRR_C_WIDE_NO_TIDE", regions(2, 38)),
|
||||||
|
("RCRR_R_DYNAMIC_NO_TIDE", regions(33, 38)),
|
||||||
|
]:
|
||||||
|
with self.subTest(scenario=scenario):
|
||||||
|
a = sample(retained)
|
||||||
|
a["sources"].append({"sourceId": "tide"})
|
||||||
|
self.assertFalse(verifier.scene_parity_valid(a, scenario))
|
||||||
|
b = sample(retained)
|
||||||
|
b["commands"]["emptyBuiltinAnnotationLayerRemoved"] = False
|
||||||
|
self.assertFalse(verifier.scene_parity_valid(b, scenario))
|
||||||
|
|
||||||
|
def test_wrong_final_extent_and_wrong_retained_count_rejected(self):
|
||||||
|
a = sample(regions(31, 33))
|
||||||
|
a["retained"][-1]["end"] = 65
|
||||||
|
self.assertFalse(verifier.scene_parity_valid(a, "RCRR_C_NARROW_NO_TIDE"))
|
||||||
|
b = sample(regions(31, 33)[:2])
|
||||||
|
self.assertFalse(verifier.scene_parity_valid(b, "RCRR_C_NARROW_NO_TIDE"))
|
||||||
|
|
||||||
|
def test_existing_static_no_tide_contract_preserved(self):
|
||||||
|
a = sample([{"begin": 0, "end": 62}])
|
||||||
|
self.assertTrue(verifier.scene_parity_valid(a, "STATIC_RC_NO_TIDE"))
|
||||||
|
self.assertFalse(verifier.scene_parity_valid(a, "RCRR_C_NARROW_NO_TIDE"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main(verbosity=2)
|
||||||
@@ -18,7 +18,10 @@ APK = ARTIFACTS / "MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk"
|
|||||||
BUILD_INFO = ARTIFACTS / "build-info.txt"
|
BUILD_INFO = ARTIFACTS / "build-info.txt"
|
||||||
PACKAGE = "org.maplibre.android.testapp"
|
PACKAGE = "org.maplibre.android.testapp"
|
||||||
ACTIVITY = f"{PACKAGE}/{PACKAGE}.activity.particle.ParticleCoreLayerValidationActivity"
|
ACTIVITY = f"{PACKAGE}/{PACKAGE}.activity.particle.ParticleCoreLayerValidationActivity"
|
||||||
SCENARIOS = ("STATIC_RC", "PBF63", "PARTICLE_OFF", "PARTIAL_RCRR", "SOURCE_CHANGE", "STATIC_RC_NO_TIDE")
|
SCENARIOS = ("STATIC_RC", "PBF63", "PARTICLE_OFF", "PARTIAL_RCRR", "SOURCE_CHANGE", "STATIC_RC_NO_TIDE",
|
||||||
|
"RCRR_C_NARROW_NO_TIDE", "RCRR_C_WIDE_NO_TIDE", "RCRR_R_DYNAMIC_NO_TIDE")
|
||||||
|
NO_TIDE_SCENARIOS = {"STATIC_RC_NO_TIDE", "RCRR_C_NARROW_NO_TIDE",
|
||||||
|
"RCRR_C_WIDE_NO_TIDE", "RCRR_R_DYNAMIC_NO_TIDE"}
|
||||||
LOG_ENTRY = re.compile(r"^[A-Z]/STEP113Gate\(\s*(\d+)\):\s*(\{.+\})\s*$")
|
LOG_ENTRY = re.compile(r"^[A-Z]/STEP113Gate\(\s*(\d+)\):\s*(\{.+\})\s*$")
|
||||||
|
|
||||||
|
|
||||||
@@ -106,6 +109,24 @@ def extract(logcat, pid, expected):
|
|||||||
return [x[1] for x in sorted(result, key=lambda item: item[0])]
|
return [x[1] for x in sorted(result, key=lambda item: item[0])]
|
||||||
|
|
||||||
|
|
||||||
|
def rcrr_segments_valid(sample, scenario):
|
||||||
|
"""Verify exact R/C boundaries in the new isolated, 64-layer PBF Test App cases."""
|
||||||
|
retained = sample.get("retained", [])
|
||||||
|
if len(retained) != 3:
|
||||||
|
return False
|
||||||
|
r0, r2, r3 = retained
|
||||||
|
if (r0.get("begin") != 0 or r2.get("end") != r3.get("begin")
|
||||||
|
or r3.get("end") != 64 or r3.get("begin") != 63):
|
||||||
|
return False
|
||||||
|
if scenario == "RCRR_C_NARROW_NO_TIDE":
|
||||||
|
return r0.get("end") == 31 and r2.get("begin") == 33
|
||||||
|
if scenario == "RCRR_C_WIDE_NO_TIDE":
|
||||||
|
return r0.get("end") == 2 and r2.get("begin") == 38
|
||||||
|
if scenario == "RCRR_R_DYNAMIC_NO_TIDE":
|
||||||
|
return r0.get("end") == 33 and r2.get("begin") == 38
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def scene_parity_valid(sample, scenario):
|
def scene_parity_valid(sample, scenario):
|
||||||
"""Fail closed on the *declared* base style, not just a loose layer count.
|
"""Fail closed on the *declared* base style, not just a loose layer count.
|
||||||
|
|
||||||
@@ -117,7 +138,7 @@ def scene_parity_valid(sample, scenario):
|
|||||||
"""
|
"""
|
||||||
if not sample.get("planValid"):
|
if not sample.get("planValid"):
|
||||||
return False
|
return False
|
||||||
if scenario != "STATIC_RC_NO_TIDE":
|
if scenario not in NO_TIDE_SCENARIOS:
|
||||||
return sample.get("basePreserved") is True and not sample.get("tideLayerExcluded", False)
|
return sample.get("basePreserved") is True and not sample.get("tideLayerExcluded", False)
|
||||||
return (
|
return (
|
||||||
sample.get("basePreserved") is False
|
sample.get("basePreserved") is False
|
||||||
@@ -131,9 +152,16 @@ def scene_parity_valid(sample, scenario):
|
|||||||
and sample.get("commands", {}).get("emptyBuiltinAnnotationLayerRemoved") is True
|
and sample.get("commands", {}).get("emptyBuiltinAnnotationLayerRemoved") is True
|
||||||
and sample.get("commands", {}).get("annotationSourcePreserved") is True
|
and sample.get("commands", {}).get("annotationSourcePreserved") is True
|
||||||
and all(source.get("sourceId") != "tide" for source in sample.get("sources", []))
|
and all(source.get("sourceId") != "tide" for source in sample.get("sources", []))
|
||||||
and len(sample.get("retained", [])) == 1
|
and sample.get("actualLayers") == 64
|
||||||
and sample["retained"][0].get("begin") == 0
|
and (
|
||||||
and sample["retained"][0].get("end") == 62
|
(scenario == "STATIC_RC_NO_TIDE" and
|
||||||
|
len(sample.get("retained", [])) == 1 and
|
||||||
|
sample["retained"][0].get("begin") == 0 and
|
||||||
|
sample["retained"][0].get("end") == 62)
|
||||||
|
or
|
||||||
|
(scenario != "STATIC_RC_NO_TIDE" and
|
||||||
|
rcrr_segments_valid(sample, scenario))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +250,7 @@ def run():
|
|||||||
"sourceReport": (
|
"sourceReport": (
|
||||||
"STEP-118 user-approved TEST-APP-ONLY 62-layer derivative; "
|
"STEP-118 user-approved TEST-APP-ONLY 62-layer derivative; "
|
||||||
"original 63-layer PBF Style remains unmodified; not STEP-114 smoke"
|
"original 63-layer PBF Style remains unmodified; not STEP-114 smoke"
|
||||||
if args.scenario == "STATIC_RC_NO_TIDE"
|
if args.scenario in NO_TIDE_SCENARIOS
|
||||||
else "STEP-113 original 63-layer PBF test scene; not STEP-114 smoke"
|
else "STEP-113 original 63-layer PBF test scene; not STEP-114 smoke"
|
||||||
),
|
),
|
||||||
"durationSecondsRequested": args.seconds,
|
"durationSecondsRequested": args.seconds,
|
||||||
|
|||||||
@@ -1198,3 +1198,5 @@ Android V3-08 单次综合验收已完成并关闭。Native `13.4.1-particle.2`
|
|||||||
- 2026-10-11 STEP119 RDC Android实机:源码锁3d989a00a822989339a6d7cb4d23acc04396670e,新APK SHA 57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135、Mac现有Gradle/NDK整包编译PASS、FZG1-2安装设备SHA一致。新STATIC_RC_NO_TIDE真实90秒R Build=1/Reuse=3276(累计)、FastDelta=1819/FullDelta=0、120帧119Fast/0Full、24Gate mismatch0,证实Symbol缓存首次Build/后续Fast生效。原63 STATIC_RC 90秒因tide缺源保持Build/Reuse/Fast全0、FullDelta=305,缺源fail-closed有效。Mac原生GTest受旧libuv环境缺失阻断,未运行13项测试;Metal/iOS、Pan/Zoom/Rotate、Source/Style异步变更、像素/人工目视仍未验,整体PARTIAL。证据docs/60_测试/STEP-119_FZG1_原PBF真实Fast验收结果_20261011.md。
|
- 2026-10-11 STEP119 RDC Android实机:源码锁3d989a00a822989339a6d7cb4d23acc04396670e,新APK SHA 57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135、Mac现有Gradle/NDK整包编译PASS、FZG1-2安装设备SHA一致。新STATIC_RC_NO_TIDE真实90秒R Build=1/Reuse=3276(累计)、FastDelta=1819/FullDelta=0、120帧119Fast/0Full、24Gate mismatch0,证实Symbol缓存首次Build/后续Fast生效。原63 STATIC_RC 90秒因tide缺源保持Build/Reuse/Fast全0、FullDelta=305,缺源fail-closed有效。Mac原生GTest受旧libuv环境缺失阻断,未运行13项测试;Metal/iOS、Pan/Zoom/Rotate、Source/Style异步变更、像素/人工目视仍未验,整体PARTIAL。证据docs/60_测试/STEP-119_FZG1_原PBF真实Fast验收结果_20261011.md。
|
||||||
|
|
||||||
- 2026-10-11 STEP119实机首次FAST_OBSERVED:APK源3d989a00a822989339a6d7cb4d23acc04396670e SHA=57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135,FZG1-2安装/preflight PASS;STATIC_RC_NO_TIDE 90秒 FastDelta1819/FullDelta0、R Build1/Reuse3276、24Gate mismatch0、Native64,missingSourceIds=[]。仅正向目标首次通过,负例/视觉/GTest/iOS未验,STEP119 PARTIAL。详见 docs/报告/STEP-119_Android真机Fast首次通过_阶段验收_v1.md。
|
- 2026-10-11 STEP119实机首次FAST_OBSERVED:APK源3d989a00a822989339a6d7cb4d23acc04396670e SHA=57d68800770d431a2ce9247406f636e7a01cc19fccaf4c59f5eb3a7c99128135,FZG1-2安装/preflight PASS;STATIC_RC_NO_TIDE 90秒 FastDelta1819/FullDelta0、R Build1/Reuse3276、24Gate mismatch0、Native64,missingSourceIds=[]。仅正向目标首次通过,负例/视觉/GTest/iOS未验,STEP119 PARTIAL。详见 docs/报告/STEP-119_Android真机Fast首次通过_阶段验收_v1.md。
|
||||||
|
|
||||||
|
- 2026-10-11 STEP-119 RCRR续验:原四段 `PARTIAL_RCRR` 在已锁 APK 真机80秒 R0缺tide(Build0/Reuse0)、R2/R3各Build1/Reuse536;FastDelta0/FullDelta596、24Gate mismatch0,安全Full回退。真机原Style Manifest证实tide索引2、clip索引31、weather实际在宽C内。新增窄C、宽C、错误动态R三种Test App RCRR_NO_TIDE对照入口和精确验证器;Style结构静态核对PASS、非Jest Python 4 tests PASS。新APK编译/实机、13项GTest、Metal/iOS和视觉仍未验证,STEP119保持PARTIAL。见docs/60_测试/STEP-119_RCRR多配置验收矩阵_v1.md及docs/报告/STEP-119_RCRR多场景局限性_阶段验收_v1.md。
|
||||||
|
|||||||
Reference in New Issue
Block a user