30 KiB
STEP-113 FZG1 PBF Layer 与 Fast Gate 诊断 Codex 完成报告 v1
日期:2026-10-11(JST)。结论:PARTIAL:诊断和专项测试场景源码已交付;构建、设备及生产113层完整等价未验收。
1. 基线、模型与授权
- Mac.lan / Darwin 24.6.0 / x86_64;仓库
/Users/tei/dev/MapLibreParticleLab。 - 起点及交付 HEAD:
particle/main@c6d13e1059d464d312ac33acac87967300fa5dc4;无 commit/push、无新 branch/worktree、无发行。 - 实际模型 GPT-6.1-Sol(
gpt-6.1-sol)/ high,从本会话01a12808-4436-7d33-bc56-9135722348b1rollout 的turn_context.model/effort核实。未切换模型、未启动其他 Codex/子代理。 - Native/Test App 的源码版本
platform/android/VERSION=13.6.1-particle.23,RN package 同为.23;没有改版本或覆盖正式制品。新诊断只存在于本次未提交源码,不能把现有正式 V23 APK 当本次制品。 - NavSea 只读 HEAD
ad9aa043fde37f87462f31de3fbd8ce008f8424b,读取时 tracked/untracked status 均无输出;Integration 本地 HEAD80667d6c343411d03a760425438e3d292f452118。没有 fetch/pull、跨项目写入或消息发送;Integration 远端核验采用用户提供的 RDC 事实。 - 起点 tracked clean;已有 STEP-110/111/113 三份未跟踪任务书均保留。子模块状态均为空格前缀,没有操作子模块。
- 已读根 AGENTS、PARTICLE_BASELINE、项目规范全部文件、总则 README 和四份有效总则、STEP-113 任务书、STEP-112 调查/记录/报告,以及 STEP-102/106 的相关实现与记录。
- 本轮不执行 CMake/Ninja/Bazel、Native 测试、Gradle/APK、ADB/安装/Logcat、Jest、发布、提交或 push。以下命令仅交 RDC 执行。
2. 实际修改与新增文件
| 文件 | 变更目的 |
|---|---|
src/mln/renderer/particle_fast_path.hpp |
24项固定顺序表、无副作用失败掩码;生产 evaluator 原样保留 |
include/mln/renderer/render_segment.hpp |
平台无关帧/phase/cache诊断值结构,现有 snapshot 可选 fastGateTrace |
src/mln/renderer/retained_underlay_runtime_state.hpp |
120帧环形缓冲、生命周期聚合、受锁保护的快照/reset/完成记录 |
src/mln/renderer/render_segment_json.hpp |
现有 JSON 出口增加可选 trace,24项状态、窗口与生命周期计数、pre/post |
src/mln/renderer/renderer_impl.cpp |
原始 input/decision 采集点、实际 pre cache validity/revision、渲染后完成记录 |
src/mln/renderer/renderer.cpp |
生命周期 reset 与没有 RenderTree 时的明确 outcome |
src/mln/map/map.cpp |
外部诊断读取携带 trace;renderer 内部读不复制历史环形数据 |
test/renderer/retained_underlay_cache.test.cpp |
新增4个 FastGateTrace.* C++ 回归用例;未运行 |
platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/Step113PbfGateScene.kt(新增) |
真 PBF、五个场景、parity证明/限制、固定预报、低频UI与分块导出 |
同目录 ParticleCoreLayerValidationActivity.kt |
菜单/Intent、scene生命周期与旧场景隔离,诊断区域临时扩展 |
docs/50_Step记录/STEP-113_FZG1_PBF_Layer与FastGate诊断_v1.md(新增) |
当前状态、RDC验收填写栏 |
| 本完成报告(新增) | 源码交付事实、命令、证据与限制 |
粒子开发记录.md |
仅末尾追加本次短记录 |
没有修改 Shader、Placement、Retained Cache 的准入/等价/回退算法、RN 类型或方法、JNI 方法签名、NavSea、Integration、构建流水线和发行版本。扩展的是任务明确授权的可选诊断 JSON 与其内部值结构,不新增公共控制 API/Host 契约。若后续需要新的公共控制面,应先走 Integration RFC。本任务不为未来接口变更提供授权。
3. B:24 Gate 同帧记录与真实性边界
每次真实 tryRenderParticleFastFrame 用已经计算好的同一个 input调用原 evaluator 一次,再独立计算掩码。没有再次调用 particleFastPathDynamicState、needsRepaint、Placement 计算或 cadence 推进。新增 Cache getter 是 const noexcept 的纯字段读取;用于观察已被 aggregate 短路掩盖的 R 状态。
knownMask=0x00ffffff:当前24条 evaluator 布尔输入全部已知;gateStatus 逐项给出 PASS/FAIL。若以后缺少输入,可通过 knownMask 显式输出 UNKNOWN。这里观测的是实际 Gate 输入;如没有 prepared scene,其已有 false 标志导致 Gate FAIL,不表示调查过一个尚不存在的 scene。
firstFailure 保存生产 evaluator 真正返回的首错;failMask 保存同一 input 的失败全集。decisionConsistent 比较首位失败与生产决定,decisionMismatch 累计不一致;任何非零值均需要保留现场,不能接受归因结果,也不会放宽生产 Gate。位0对应顺序1;enum 的 camera/viewport 数值顺序不能用作掩码顺序。
| 顺序 | 失败名 | FAIL 谓词 |
|---|---|---|
| 1 | no-prepared-tree | !hasPreparedTree |
| 2 | retained-disabled | !retainedEnabled |
| 3 | cache-invalid | !cacheValid |
| 4 | revision-mismatch | !revisionMatches |
| 5 | content-mutation | !contentRevisionMatches |
| 6 | viewport-changed | !viewportMatches |
| 7 | camera-changed | !cameraMatches |
| 8 | update-parameters-changed | !updateParametersMatch |
| 9 | style-not-loaded | !styleLoaded |
| 10 | boundary-changed | !boundaryMatches |
| 11 | topology-changed | !topologyMatches |
| 12 | static-unstable | !staticStable |
| 13 | placement-or-fade | hasPlacementTransition |
| 14 | pending-changes | hasPendingChanges |
| 15 | non-particle-transition | hasNonParticleTransition |
| 16 | non-particle-repaint | hasNonParticleRepaint |
| 17 | fading-tiles | hasFadingTiles |
| 18 | no-particle-repaint | !particleNeedsRepaint |
| 19 | still-image-request | stillImageRequest |
| 20 | unsupported-mode | !continuousMode |
| 21 | debug-options | !debugDisabled |
| 22 | unsupported-continuous-layer | unsupportedContinuousLayer |
| 23 | unsupported-scene | !supportedScene |
| 24 | annotation-mutation | annotationMutation |
因此 CacheInvalid 同帧也会保留 #22、#23 的真假,不再通过后续Full快照推测此前Gate。
每帧有 lifecycle 内唯一 sequence、renderer frame、steady-clock 的 updateTimeNs;没有树时多个尝试可以共用一个尚未完成的 renderer frame,关联主键是 lifecycle+sequence。不把 updateTimeNs 当 UTC/forecast。外层原有fastPathHit/Miss/Full atomics沿用原快照语义,可能与正在写入的trace末帧相差一个调用阶段;逐帧归因以frame记录为准,不把外层字段拼成额外原子帧。
cacheInputs是实际 pre-fast cache exists/valid/buildRevision/staticRevision;最多16个 R,超限明确cacheInputsTruncated=true,所有 aggregate Gate 仍完整。pre保存判定阶段的缓存计数/失效/回退原因与上一已完成 RenderTree 诊断快照。preFastPlacementTransition才是本次 Gate #13 的当前 Controller 值;placementTransitionsEnabled来自本次 UpdateParameters。post在渲染末尾取得同帧 R build/reuse/invalidation/fallback、sourceReady/stable、decision、actualExecution、Placement changed/transition/fade与Full计数。Full、Fast、无树分别有明确 outcome;中途异常或尚未结束时completed=false/post=null。placementBasis区分历史 RenderTree、当前 Full tree、当前 Fast tree(未重新计算Placement);没有完成过的诊断快照标 UNKNOWN。没有将 post Full 数据回填 pre Gate。- 每phase最多16个R;
retainedSamplesTruncated明示超限。无同帧每Symbol输出签名、旧Placement options/duration/commitTime/fadeStartTime、CPU/GPU阶段计时,这些不在本次实现中伪造。 - Debug 的
processSimulationAdvance复用现有进程级 atomic 计数;Release为null。它不是单Map的计数,也不等于Fast尝试或FPS。
120帧全部Gate每次尝试都记录;容量满时覆盖最早帧,overwritten 累计。生命周期 gates[].failures/firstFailures 保留聚合;windowFailures、窗口首末序号、窗口 Full/Fast/无树计数另行导出。默认30fps时120帧约4秒,真实渲染频率可能更高,不能承诺完整60秒逐帧档案。
环形记录在 render thread 更新;写入、完成、reset和外部copy沿用 rangeMutex。Android UI只读现有共享snapshot,不操作Renderer可变对象。内部render snapshot默认不复制trace;只有外部 Map::getRenderSegmentDiagnostics() 包含历史。reset发生于绑定新的 runtime state、观测到 styleLoaded true→false、context lost、Renderer.clearData;每次普通 Full miss清prepared tree不会清trace。sceneGeneration/configRevision另用于区分UI场景切换;同步加载没有暴露false帧时,不能假定trace epoch必然随UI场景切换。
新增CPU工作为O(24+R)、固定容量历史;没有额外GPU pass。每帧仍有小型vector/string副本与短mutex临界区,外部读取序列化120帧也有成本。内存字节数和CPU成本没有实测,不声明低于某一百分比;RDC需量测。没有诊断开关的新RN API;如需成本对照,应使用同环境基线源码制品与本次制品并记录差异。
4. A:Style、Layer 与场景等价度证据
| 项目 | 证据等级与当前结论 |
|---|---|
| 正式Style/Sprite/Glyph/VectorTile URI | SOURCE-PROVEN:NavSea src/config/builtinRuntimeUrlConfig.ts 与新场景常量相同 |
| NavSea当前分段选择器 | SOURCE-PROVEN:RenderSegmentHost.tsx 为R→C,C从 rn-weather-color 开始;不是现场四段计划 |
| 天气片段 ID/type/source | SOURCE-PROVEN:particleStyle.ts 调用shared fragment,追加到顶;shared packages/maplibre-particle-rn/src/index.ts 定义 rn-weather-fields、rn-weather-color、rn-weather-particles |
| 正式63层保序/显隐/完整定义 | TEST-APP-STRUCTURAL:运行时从正式URL加载,要求63层和实际锚点ID;完整原始定义逐层不变、顺序不变,并导出生产manifest与实际Native styleLayers。尚未在设备执行该证明 |
| Sprite/Glyph/VectorTile访问成功 | NOT-VERIFIED:本机web open失败;urllib回读失败于域名无法解析,没有服务器JSON/SHA或瓦片访问成功证据 |
| 113层及[0,13)/[13,33)/[33,107)/[107,113) | 用户STEP-112历史现场输入;本轮没有同版本完整Layer/Source/visibility/业务数据快照,NOT-VERIFIED,未完整复制 |
| 旧NavSea FZG采样 | 只读找到V15报告与129层采样;年代/版本/层数均不同,不用于补造当前113层 |
| 本轮真机/性能 | DEVICE-MEASURED:无本轮结果 |
生产URI分别为:
- Style:
https://pbf.jpcn.ccwu.cc/style/style.navsea-delivery-full-semantic-extentfix.json - Sprite:
https://pbf.jpcn.ccwu.cc/sprite/sprite - Glyph:
https://pbf.jpcn.ccwu.cc/fonts/{fontstack}/{range}.pbf - VectorTile:
https://pbf.jpcn.ccwu.cc/pbf/pbf-delivery-full-20260418-rebuild/{z}/{x}/{y}.pbf,source=navsea_delivery。
场景会检查真实回读的资源URI;变更或缺失则显示BLOCKED并导出原因,不切换假地图。productionFingerprintSha256 是SDK回读序列化JSON的UTF-8 SHA-256,不是HTTP原始字节SHA,且URL本身可变。导出styleVersion/name/metadata(styleVersion是Style规格版本,包版本未知时为null)、生产/增强fingerprint、basemanifest、请求plan、最终Native所有Layer的index/id/type/source/visibility,以及段边界与层名。Native可能追加Annotation等内部层,不能把JSON基础63层等同实际总层数。
| 场景 | 行为与等价限制 |
|---|---|
| PBF63 | 正式63层原定义;无测试天气片段;全RETAINED,实际总层数以Native为准 |
| STATIC_RC | 原63层+正式类型的天气/粒子片段(JSON65层);保序append;当前NavSea源码RC选择器;不等价NavSea全部动态业务层 |
| PARTICLE_OFF | 与STATIC_RC同样层序,粒子visibility=none;WeatherColor/forecast/camera保持对照 |
| PARTIAL_RCRR | 原63层+天气片段,片段放在实际 clip-outline 后;四段锚点为 sea-area-fill、special-pattern-line-754、实际回读的最后生产层ID;明示结构RCRR,与现场113层/数字边界不同 |
| SOURCE_CHANGE | STATIC_RC加一个独立GeoJSON/circle测试Source;显式菜单单次更新;结构探针,不冒充AIS/Radar/航线等生产数据 |
所有带天气场景使用既有ECMWF canonical两个时间片(2026080700/06),forecast请求 1786060800000 ms,PAUSE,targetFps=30,粒子1024。与NavSea当前QBIN/预报业务输入不等价。命令接受结果逐项保存;实际Native预报时间没有新增查询API,actualForecastTimeObservedMs=null,不把Host请求值当Native独立回读结果。camera请求33.45/129.97、zoom10.5、bearing/pitch0;场景禁用手势,退出恢复原手势设置。静态轮询不改Source/Symbol/forecast/camera。
Native准入限制保持原样;RCRR结构模式预期可以暴露不支持的C层和Symbol R阻塞,但这只是源码预期,不是已经在FZG测到的结果。
5. C:UI、导出及精确RDC命令
入口:Test App STEP 093 → STEP-113 FZG1-PBF GATE。五个场景、EXPORT LAST SNAPSHOT、MUTATE PROBE SOURCE ONCE、退出。加载中或失败时也保留低频诊断读取,sceneReady=false/blockedReason明确标注,不能把可能仍在加载的旧Native层表当已完成场景。每3秒只有一次Native诊断查询;UI首错来自trace末帧,失败排名来自同copy聚合,各段显示范围/state/build/reuse/invalidation。仅STEP-113期间增大诊断区域,退出恢复。
每30秒一条逻辑summary(通常少量物理Logcat分块);不是每33ms输出JSON。完整120帧和Layer表仅手动导出最近一次copy,写App私有 files/step113-<SCENARIO>-<elapsed>.json 并使用标签 STEP113Gate 输出Base64分块。每块payload≤2400 ASCII字符,携带schemaVersion/kind/exportId/chunkIndex/chunkCount/encoding;按exportId和chunkIndex完整拼接后Base64解码,缺块不能当完整证据。手动完整导出会产生较多块,优先直接回读私有JSON文件。
以下仅RDC执行,本轮Codex没有执行。先在macOS普通Terminal核对设备主ABI与标准脚本的x86_64一致;不同则停止本构建流程并记录,不自行改脚本/环境:
cd /Users/tei/dev/MapLibreParticleLab
step113_abi="$(adb -s 192.168.200.139:5555 shell getprop ro.product.cpu.abi | tr -d '\r')"
step113_abilist="$(adb -s 192.168.200.139:5555 shell getprop ro.product.cpu.abilist | tr -d '\r')"
printf 'FZG1-2 primary ABI=%s; ABI list=%s\n' "$step113_abi" "$step113_abilist"
test "$step113_abi" = x86_64 || { echo 'ABI不一致,停止'; return 1 2>/dev/null || exit 1; }
./tools/particle_android_validation/build_validation_apk.sh
标准产物:artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk、build.log、build-info.txt;脚本记录commit/branch/dirty/SHA/体积并自验ZIP与Native ABI,失败不得复用旧APK。本轮源码未提交,build-info里的dirty必须真实,另保留任务文件diff/hash以证明制品来自本次修改。
安装前RDC核对现存同包签名,签名不匹配不得自动卸载用户数据;保留INSTALL_FAILED错误。安装与静态场景启动:
adb -s 192.168.200.139:5555 install -r artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk
adb -s 192.168.200.139:5555 shell am start -S -n org.maplibre.android.testapp/org.maplibre.android.testapp.activity.particle.ParticleCoreLayerValidationActivity --es step113_scenario STATIC_RC
adb -s 192.168.200.139:5555 logcat -v raw -s STEP113Gate:I '*:S' > artifacts/maplibre-particle/android-validation/step113-static-rc.log
最后一条在RDC普通前台Terminal采集,窗口完成后Ctrl-C。其他场景各用一条明确启动命令,并独立保留日志:
adb -s 192.168.200.139:5555 shell am start -S -n org.maplibre.android.testapp/org.maplibre.android.testapp.activity.particle.ParticleCoreLayerValidationActivity --es step113_scenario PBF63
adb -s 192.168.200.139:5555 shell am start -S -n org.maplibre.android.testapp/org.maplibre.android.testapp.activity.particle.ParticleCoreLayerValidationActivity --es step113_scenario PARTICLE_OFF
adb -s 192.168.200.139:5555 shell am start -S -n org.maplibre.android.testapp/org.maplibre.android.testapp.activity.particle.ParticleCoreLayerValidationActivity --es step113_scenario PARTIAL_RCRR
adb -s 192.168.200.139:5555 shell am start -S -n org.maplibre.android.testapp/org.maplibre.android.testapp.activity.particle.ParticleCoreLayerValidationActivity --es step113_scenario SOURCE_CHANGE
不要把这些命令连续执行当场景测试;每个场景至少预热10秒、观察60秒、手动导出窗口,再切下一场景。SOURCE_CHANGE先导出baseline,单击手动探针变化,等一次3秒刷新后再次导出;不添加周期Symbol更新。
点击 EXPORT LAST SNAPSHOT 后回读最近文件(run-as仅适用于该Debug App):
step113_file="$(adb -s 192.168.200.139:5555 shell run-as org.maplibre.android.testapp ls -t files | tr -d '\r' | rg '^step113-.*[.]json$' | head -n 1)"
test -n "$step113_file" || { echo '未找到手动导出文件'; return 1 2>/dev/null || exit 1; }
adb -s 192.168.200.139:5555 exec-out run-as org.maplibre.android.testapp cat "files/$step113_file" > "artifacts/maplibre-particle/android-validation/$step113_file"
shasum -a 256 "artifacts/maplibre-particle/android-validation/$step113_file"
adb -s 192.168.200.139:5555 exec-out screencap -p > artifacts/maplibre-particle/android-validation/step113-screen.png
adb -s 192.168.200.139:5555 logcat -b crash -d > artifacts/maplibre-particle/android-validation/step113-crash.log
如果只保留Logcat,使用下面的离线重组命令;每个导出必须收齐chunkCount,否则直接报错:
python3 - <<'PY'
import base64, json
from pathlib import Path
root = Path('artifacts/maplibre-particle/android-validation')
groups = {}
for line in (root / 'step113-static-rc.log').read_text().splitlines():
try:
c = json.loads(line)
except json.JSONDecodeError:
continue
if c.get('encoding') != 'base64-utf8':
continue
key = (c['exportId'], c['kind'])
count, parts = groups.setdefault(key, (c['chunkCount'], {}))
assert count == c['chunkCount'], key
parts[c['chunkIndex']] = c['payload']
for (export_id, kind), (count, parts) in groups.items():
assert set(parts) == set(range(count)), ('缺块', export_id)
raw = base64.b64decode(''.join(parts[i] for i in range(count)), validate=True)
json.loads(raw)
(root / f'step113-{export_id}-{kind}.json').write_bytes(raw)
PY
RDC的macOS Native定向检查可按当前preset执行(历史缺libuv阻塞不代表当前环境仍相同;若失败保留首错,不扩大改依赖):
cmake --preset macos-metal
cmake --build build-macos-metal --target mbgl-test-runner --parallel 3
build-macos-metal/mbgl-test-runner --gtest_filter='FastGateTrace.*:ParticleFastPath.*:RenderSegmentDiagnostics.*:RenderSegmentPlacementFree.*:RenderSegmentLocality.*' --gtest_color=no
配置失败就停止该链;不运行旧runner冒充新源码通过。Metal host测试不能替代Android OpenGL/实体机/iOS验收。
6. 已执行静态检查与未做项
已执行:只读Git/源码/文档调查、diff范围检查、git diff --check(退出0);新增文件另用no-index whitespace检查。静态文本核对24条谓词及极性/顺序一致;生产 evaluator 与HEAD逐字相同;STEP-102 fixture与500ms poll逐字未变。最终hash与append-only核对见第7节。
4个测试源码覆盖:全部24独立失败位/生产首错顺序;CacheInvalid与#22/#23同帧并存、137次记录后120条有序窗口与reset;pending/null post/错误shadow显式计数和完成幂等;18个R截断及pre/post独立缓存计数。没有运行这些测试,没有C++/Kotlin编译或语法编译PASS结论。
本轮无APK/AAR、体积或SHA,无设备运行日志、截图、FPS、CPU、trace开销或性能改善数字。没有已观察到的构建/测试失败;未执行不表示会通过。
剩余RDC事项:Native/Kotlin编译和上述定向测试;设备ABI/制品SHA/版本证据;正式资源加载、原63层manifest/实际层序;plan接受与最终valid原因;所有24状态与首错一致性;cache-invalid同帧后续失败;Full/post和pre分离、Source变更前后、粒子关闭对照;reset/退出/恢复与旧场景回归;开销/CPU和截图。APK成功仅是构建证据。
113层完整等价仍需同版本真实Layer/Source/业务数据/显隐/选择器快照后才能扩展;本任务交付的部分模式不为生产Full循环提供完整因果或性能验收结论。
7. 收尾证据
- STEP-110任务书SHA-256:
33037df71b4b30aa7956d59f4b99f77af3085405b24111bc0fe11ec857a93db0。 - STEP-111任务书SHA-256:
f3a5806f25384bf46055db2edfea0d21bfbc4124184bc813b46e38b8079c1ec4。 - STEP-113任务书原样SHA-256:
4e3fef391dc3addef2702b3d588c1fcc8f79b898b5d9004bfc1410070533e0b4。 - HEAD保持起点,暂存区为空;仅任务源码/测试、两个新交付文档和开发记录追加,既有三任务书未暂存。没有远端HEAD回读、commit/push或制品发布行为。
- 开发记录的HEAD原始160442字节前缀完全保留,原SHA-256=
070aaeaf85aa8fdbe8b15a899f74fd492a0e3eb2b6442b37cb3d5ee9724dbd24;本次仅末尾追加1120字节(7行)。静态检查是范围与一致性证据,不是全任务PASS。
RDC 独立验收补记(2026-10-11,设备证据)
以下是 Codex 退出后 RDC 新执行的证据,不修改上文 Codex 未构建/未实测的历史结论。本次阶段判定:PARTIAL;Android 构建 PASS;五场景稳定基线采样 PASS;113 层等价与性能 NOT VERIFIED。
- 环境:Mac、particle/main;构建源码基于
c6d13e1059加 STEP-113 未提交改动,build-info 明确 git_dirty=true。此 APK 不是 Source Lock / 正式发行。 - 标准 build_validation_apk.sh 于 2026-10-11 08:35:08 JST 退出码 0;Gradle BUILD SUCCESSFUL in 19m 22s;Java 17.0.20.1;OpenGL/x86_64;ZIP/ABI/体积/SHA 自检通过。
- APK:artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk;66,587,454 bytes;libmaplibre.so 40,033,976 bytes;SHA-256 0054248bc3872e8670df4e9a10d11f1d65c0912a0482586cd7a247e880a6eaef。记录:同目录 build-info.txt、build.log。
- 设备:FZG1-2,ADB 192.168.200.139:5555,主 ABI x86_64;明确 -s 的 adb install -r 返回 Success,未卸载数据;设备安装后版本 13.6.1-particle.23。正式 PBF Style 模式运行并加载。启动前数秒 sceneReady=true 但 Native Layer=0 / plan not-configured 是加载暂态;只接受之后的 Native Layers 非零、planValid=true 稳定记录。
- 五个场景均由 ADB 明确 serial 启动;STEP113Gate Logcat Base64 summary 成功还原。每场景实际设备稳定状态的 decisionMismatch 都是 0。Full/Fast/Attempts 为生命周期累计,并非精确 60 秒窗口。
| 场景 | Native Layers | Attempts | Full | Fast | Retained 及关键证据 |
|---|---|---|---|---|---|
| PBF63 | 64(63+内部层) | 106 | 106 | 0 | R[0,64) Build0,unknown-dependency;无粒子持续驱动 |
| STATIC_RC | 66 | 876 | 875 | 0 | R[0,63) Build0,unknown-dependency;unsupported-continuous-layer、unsupported-scene 各876 |
| PARTICLE_OFF | 66 | 70 | 70 | 0 | no-particle-repaint=70;非相等时长性能对照 |
| PARTIAL_RCRR | 66 | 862 | 861 | 0 | R0[0,3) unknown-dependency;R2[39,64) 与 R3[64,66) Build0/static-placement;两个 unsupported Gate 各862 |
| SOURCE_CHANGE | 67 | 888 | 888 | 0 | 基线已记录;没有执行菜单手动 Source mutation |
- STATIC_RC 同帧失败全集汇总 CacheInvalid=870、revision-mismatch=871、placement-or-fade=780;PARTIAL_RCRR CacheInvalid=856。这些失败条件可能在同一帧并存,不能累加为帧数。即使修复缓存 Build,也还有 #22/#23 与其它独立 Gate。
- 设备摘要 JSON(不纳入 Git):artifacts/maplibre-particle/android-validation/step113/ 下的 pbf63-summary-ready.json、static-rc-summary.json、particle-off-summary.json、partial-rcrr-summary.json、source-change-baseline-summary.json。它们只是低频 summary,不是导出的完整 120 帧。
- 仍 NOT VERIFIED:原 NavSea 113 层完整 Layer/Source/显隐及真实四段边界;实际 PBF/Sprite/Glyph 画面截图;Source 单次变更后前后对照;120帧手动详情导出;C++ GTest 运行;reset/后台、旧 STEP-102 场景回归;CPU/GPU/诊断开销;生产性能提升、正式发行。不得把部分结构等价当成现场复测或将 STEP-113 判为 CLOSED/PASS。
- 下一阶段必须分别处理 retained first-build 的安全准入、unsupported continuous layer、unsupported scene;不能直接删除 Gate 放行。
RDC 第二轮设备验收(2026-10-11:完整窗口与Source变更)
本轮状态:设备逐帧诊断 PASS、单次Source变更链路 PASS,完整113层等价与生产优化仍 PARTIAL。 本记录追加在原有RDC基线结果之后,旧内容中的“未执行单次Source mutation/120帧导出”是第一轮结束时的历史状态,不代表第二轮。
- 在设备 FZG1-2、ADB 192.168.200.139:5555、版本 13.6.1-particle.23 上运行 SOURCE_CHANGE;通过屏幕中的 STEP 093 → STEP-113 → EXPORT LAST SNAPSHOT,使用明确serial的 adb exec-out run-as 回读 App 私有JSON;文件字节分别为变更前 277980、变更后约272KiB。精确位置:artifacts/maplibre-particle/android-validation/step113/source-change-before-full.json 和 source-change-after-full.json,均保留在 Mac 本机、未纳入Git。
- 变更前 trace:lifecycle 1,attempts 13859,capacity/windowCount 120,最新119个完成的Full帧、0 Fast帧、最后1帧为pending、decisionMismatch=0;变更后 trace:同lifecycle,attempts 17476,windowCount=120,同样119个已完成Full、0 Fast、decisionMismatch=0。相同frame中前置状态 pre 的 placementBasis 标为上一完成RenderTree,post 完成Full才使用当前Full tree;knownMask覆盖24条Gate。
- 在 SOURCE_CHANGE 场景操作一次 MUTATE PROBE SOURCE ONCE。Logcat解码的 source-command:mutation=1;变更后导出 commands.sourceMutationCount=1;Native lastMutation.sourceId=step113-source-probe,affectedSegmentIndices=[1],事件 TileMutation。变更前 lastMutation.sourceId=navsea_delivery,affectedSegmentIndices=[0]。累计 content-mutation Gate failure 从12变为14,但中间同时有正常瓦片更新,不得把全部增量单独归因为这一次probe。120帧环形窗口会覆盖发生瞬时变更时的精确帧,故本轮只确认命令/Native依赖定位,不声称捕获到单次Mutation帧的全部过渡时序。
- 从变更后120帧中统计119个 completed 样本:首错 cache-invalid=119/119;同一帧 Gate #3 cache-invalid=119、#4 revision-mismatch=119、#12 static-unstable=105、#13 placement-or-fade=105、#22 unsupported-continuous-layer=119、#23 unsupported-scene=119。24Gate shadow 对应生产首错持续吻合,decisionMismatch=0。该统计是窗口而非全应用时间的FPS度量。
- PBF同源核验:原始63层按SDK回读生产Style逐层定义保序、baseLayersPreserved=true;spec version=8,源Style名称 NavSea Delivery Full Semantic ExtentFix;productionFingerprintSha256=e0f9c2d1df38ae5d5953b561c52efe2f8590336de80b988e1d2935580d30b996(SDK回读序列化JSON,不是HTTP包字节)。SOURCE_CHANGE运行时67层,连续段[63,67)依次是 weather-color、raster-particle、测试circle、内建 org.maplibre.annotations.points symbol。STATIC_RC的连续段[63,66)同样包括内建annotation symbol。现有 continuousRangeSupportsParticleFastPath 要求其范围内每一层均支持 retained dynamic range;因此这些普通circle/symbol使Gate #22持续失败;这项结论为“源码判定+本机层清单”,未进行绕过Gate的运行实验。
- Gate #23 supportedScene 源码逻辑与 retainedSupported、fastContinuousSupported 及单C配置有关,#22与#23不是根因完全独立的两次失败;二者虽为不同Gate,却可能共享同一个不支持的C层根因。Retained R[0,63)仍持续 Build0、unknown-dependency;部分RCRR其它R也有static-placement。不能只消除C阻断就承诺Fast会成功。
- NavSea只读核对:当前src/map/particle/RenderSegmentHost.tsx 配置 R→C,从 rn-weather-color 开始;旧STEP-112的FZG1 113层RCRR_PREFIX属不同运行配置。同版本113个Layer的完整Source/ID/type/visibility/业务数据清单仍缺,不能把TEST-APP-STRUCTURAL的63/66/67层宣称为113层完整等价。FZG1-2存在debug NavSea安装,但本轮未启动/修改NavSea用户数据。
- Android设备截图已采集:artifacts/maplibre-particle/android-validation/step113/step113-source-change-screen.png(1920×1200),仅归档,未进行NavSea同版本逐像素比对。Mac Native GTest CMake配置尝试退出码1:缺少libuv(记录/tmp/particle-step113-macos-cmake.log);未安装依赖,未进入GTest构建与运行,不记PASS。
- 后续受保护顺序:先由跨项目负责人获取NavSea同版本113层完整只读snapshot及真实selector;然后在Test App精准构造Layer/Source/顺序并获取120帧一对一同条件比较;分别建立R Build准入、C范围支持、Scene聚合依赖的源码及像素等价证明;通过后才能在Shared Core按受控范围修改Gate逻辑。禁止在证据不足时关闭 fail-closed Gate。RDC未在本轮运行新Android编译、改变渲染逻辑或做正式发行。