Files
CM95/docs/CM95_S52_语义守恒与运行时能力审计标准_v2.md

18 KiB
Raw Permalink Blame History

CM95 S-52 语义守恒与运行时能力审计标准 v2

日期:2026-09-20。适用目标:绑定固定 OpenCPN 源码、明确 Production Plan 与具体 target renderer 的流程等价审计。

1. v2 的作用与生产边界

本标准升级 v1 的 source/presentation/delivery/runtime 守恒要求,新增代码优先的 Gate A–I。它是审计标准,不表示现有生产 gate 已经实现这些新增检查,也不改变产品功能、registry、PBF schema 或 importer。

Data Release PASS 与 Target Portrayal PASS 必须继续分开。资源齐全、PBF可解码、delivery字段存在、capability写IMPLEMENTED、截图看起来接近,分别只能说明局部事实。

审计真值链:

固定 OpenCPN 源码 → typed CM93/S57 object view → Lookup与初始规则 → CSP分支/子调用 → 返回有序指令 → parser规则 → 分阶段renderer及副作用

随后正向对照:

CM95 Source → s52.py → csp.py → presentation / PBF facts → style compiler → target runtime → 每条primitive consumer

不得从最终截图、输出symbol或已损失的PBF反推原始OpenCPN分支,再据此声称等价。

2. 固定基线与证据绑定

每次审计必须记录:

  • OpenCPN完整commit、固定目录、源码文件SHA-256;先校验,失败立即停止。
  • CM95起始HEAD、branch、git status --short --branch、实际审阅文件SHA;HEAD不能代表工作区未提交代码。
  • dataset/fingerprint、Plan ID、Builder/Production版本、AOI、zoom/scale ladder、mapping/policy、FID manifest、Lookup IR、resource contract与release/PBF目录及哈希。
  • target renderer及版本、运行时设置快照、display category、point/boundary table、颜色表、depth/height单位、SCAMIN、display scale、DPI/pixel ratio、raster/vector与GL/DC等适用条件。

唯一固定源码不包含的上游资源或关联对象实现应标证据不足。历史artifact中的commit字符串或资源hash一致可以证明链路一致性,不能自动补足独立上游定义证明。无正式release时允许count=null并说明evidence unavailable,但代码分支审计仍须完成。

v2 本轮固定源码为 docs/外部参考/OpenCPN源码基线_f7211b4e/,commit f7211b4e1874c453e37a7f190aa191c55a25c32e;未来换基线必须新建目录,不能覆盖旧目录或移动冻结tag。

本轮实例绑定:CM95 审计输入 HEAD 1a07406e6e11fde0425f81b54c7f4a3d2aff6d49;Production Plan ID 57e72826db1d3e3e69f0b3b084bef4fb9469b5edc47dc0030fc2ec3e46adecf9;release cm95-d1-62a85bd40d3a-57e72826db1d。配套报告与 JSON 记录 12 组、206 条组合式 branch 记录,以及已完成扫描的 5064 个 PBF、1976 个交付 signature;这些数量不等于已证明等价的完整输入数量。总体 Target Portrayal 为 FAIL;Gate A/B/C/D/E/H/I 为 FAIL,Gate F/G 为 NOT_PROVEN。Data Release PASS 仅引用既有 manifest,本轮没有重新验收或提升任何运行时能力状态。

3. 继承 v1 的语义守恒不变量

3.1 Physical Entity 与 Presentation 分离

同一relation group可以把多个source components合成一个物理delivery Feature,但必须保留component trace。若有N条独立LIGHTS source record,则必须保留N条独立presentation,不能以物理实体去重删除presentation。

审计分别计算source entity数、presentation数、instruction数、resource数和tile occurrence数。数量相等还不够,必须比较canonical signature multiset,避免A+B变成A+A。

3.2 Presentation Signature 与 Tile Occurrence

每条LIGHTS signature至少覆盖source_record_index、CSP、display category/priority、light mode/symbol、CA outline/color/width、start/end/radius/sector radius、sector sweep、nominal range、rotation/obscured、label/text。

同一个稳定Feature ID的expected signature multiset必须与actual相等;跨tile出现时signature集合必须守恒。合法按tile选取的不同source成员应先按production实际选择逻辑定义expected,不能把范围差异伪装成payload drift,也不能忽略真实drift。

多个LIGHTS必须保留s52_light_presentations完整数组;主scalar只用于兼容。CA、SY、TX分别审计数组consumer,CA消费数组不推出其他两者也消费数组。

3.3 Production Scope

Source expected scope必须重放Plan+policy+coverage+tile buffer,而不只是裸AOI bbox:

  1. 每个计划tile计算生产相同的buffer expanded bounds。
  2. 按zoom scale ladder顺序,以finer coverage先占区域,coarser仅进入剩余visible region。
  3. AOI边缘合法buffer带入的source同样计入;不能直接按AOI删除。
  4. 在该tile/native_scale/visible region内实际selected成员上重新选relation base和LIGHTS。
  5. expected/actual tile occurrence set与signature multiset逐项相等。

source→presentation、presentation→PBF、PBF→consumer是独立阶段;只扫描PBF不能证明第一段未丢数据。

3.4 CA 与资源

CA使用屏幕毫米语义,不得预烘焙成地理圆。完整证据包括outline、arc、sector angles/legs、bearing转换、设备像素/逻辑像素、尺度相关缩放及render order。固定上游GL/DC可能有不同路径,必须明确target比较哪一路。

SY/AP/LC资源存在性、制作正确性、branch实际引用、target实际消费是四个独立检查。资源存在不等于primitive完整执行。

4. 审计状态及维度

状态 定义
PASS 在声明输入域与环境内,有完整固定源码→决策→中间事实→consumer证据证明等价
PARTIAL 已实现部分分支、primitive或近似表现;不得用于strict portrayal PASS
FAIL 有明确缺失、多出、错误条件、参数、次序或副作用
NOT_IMPLEMENTED 对应层没有实现
NOT_PROVEN 有实现但证据不足,或上游该路径行为不确定;必须记录缺证及如何补证
NOT_OBSERVED_IN_REAL_DATA 源码分支保留,完整正式数据扫描未观察到;不是实现状态,也不是PASS
UPSTREAM_RESOURCE_MISSING 已证明固定上游资源缺失;若仅历史contract报告而固定定义不可得,另记reported anomaly,独立验证保持NOT_PROVEN

每条记录分别保存Python/decision、PBF/facts、consumer、overall、observation状态。某branch族FAIL不意味着其全部具体输入必然出错,例如Q/T可为空;必须写明失败的条件或反例。

PREVIEW_ONLY、NOT_IMPLEMENTED、capability missing、IMPLEMENTED缺实现证据均不能strict PASS。branch内部有FAIL不能被CSP总体PARTIAL或资源PASS覆盖。无数据或缺失属性不能按0计数;源码缺失不能按“常见规范应如此”猜测。

5. Gate A — OPENCPN_FLOW_EQUIVALENCE

进入CSP之前必须逐项证明:

  • CM93 class substitution、typed attribute conversion、原始属性presence与null/unknown语义。
  • geometry及S57/S52 class、point/boundary/line table选择。
  • Lookup条件排序、数值/字符串/list/空suffix/wildcard/undefined匹配、fallback及没有Lookup的行为。
  • initial instruction string、DISC、DPRI、radar priority及初始普通指令与CS的相对位置。
  • SCAMIN、display scale、对象category mutable等入口及会改变CSP可达性的转换。

至少核对ITDARE→DEPARE、SPOGRD→DMPGRD、FSHHAV→FSHFAC、OFSPRD→CTNARE,以及$AREAS的$SCODE=II25属性值变为BACKGROUND。不能把后一项误写为对象class改为BACKGROUND。

源geometry与delivery geometry分别记录,AREA生成outline或代表点不能因此按LINE/POINT CSP重算。Lookup IR如果只来自CM95当前resource input,须注明无法独立证明与固定上游资源一致的边界。

6. Gate B — CSP_BRANCH_EQUIVALENCE

第一批必须覆盖12组:OBSTRN04、WRECKS02、UDWHAZ03、SOUNDG03、LIGHTS05/LIGHTS06、DEPARE01/DEPARE02、DEPCNT02、SOUNDG02、QUAPOS01/QUAPNT01/QUALIN01、SLCONS03、RESTRN01、RESARE02。

每个branch至少包含:稳定branch_id、procedure、source geometry/class、typed attributes的presence/value条件、mariner参数、关联对象条件、阈值、nested calls、完整有序sequence、category/priority/SCAMIN副作用、资源、各层实际行为、real_data_count及计数单位、状态、文件/函数/行号证据与unresolved items。

允许组合式矩阵:共享前缀、后缀、数值格式化、阈值选择分别编号,但必须给出明确组合顺序、父子引用、互斥/覆盖条件。参数stage不得冒充完整terminal branch;branch记录数不得冒充互斥输入域数量或测试覆盖率。SOUNDG数字、Q、OBJNAM后缀不能仅用不展开的名称“支持”。

必须区分可达实现、注释、#if 0、early return后的死代码和注册为NULL的占位。LIGHTS05实际进入LIGHTS06;DEPARE02调度到DEPARE01;hazard调用_UDWHAZ03不等于直接CS(UDWHAZ03)。上游未初始化变量或失败转换不应自行“修正”成理想算法,标NOT_PROVEN并保存源码证据。

7. Gate C — NESTED_CSP_CALL_GRAPH

从固定源码提取真实图,记录caller/callee、调用条件、参数、返回串插入位置、side effect及所在层。至少包括:

  • OBSTRN04/WRECKS02→_UDWHAZ03、SNDFRM02(sounding formatting)、CSQUAPNT01。
  • LIGHTS05→LIGHTS06→_selSYcol/_LITDSN01。
  • SOUNDG02→MP→RenderMPS→每点SOUNDG03→SNDFRM02。
  • QUAPOS01→CSQUALIN01/CSQUAPNT01;RESTRN01→_RESCSP01。

画出primitive和mariner-dependent node,标注Python、PBF、style、JS中的决策位置及精确断点。必须另有文字解释,不能只给Mermaid。普通C++ helper串拼接和generic CS opcode递归是不同路径,不能混为一谈。

8. Gate D — INSTRUCTION_SEQUENCE_EQUIVALENCE

以完整ordered Rule Chain比较,不能只比较SY代码集合。分别记录:

  1. initial LUP instruction。
  2. CSP raw returned string(含必要的record separators/异常格式)。
  3. parser得到的规则及参数/顺序。
  4. renderer各pass执行、visibility/filter、state mutations及最终消费。

至少识别SY、TX、TE、SOUNDG glyph chain、MP、CA、AP、AC、LS、LC、OP、CS;nested展开保留provenance。必须检测missing/extra primitive、次序变化、参数变化、side effect变化、扁平化损失、初始规则被dict覆盖、多个CS/多个同类opcode被压缩。

不得先假设OP有priority执行语义;固定parser若忽略OP,就以忽略作为本基线实际行为。面积AC/AP与对象pass独立时,返回串顺序不自动等于跨pass屏幕次序。

精确反例必须记录输入、完整expected/actual、源码anchor和差异类别。手工推导expected与实际运行OpenCPN oracle应分开标注;Python/Node直接执行当前代码的结果不能包装成OpenCPN执行结果。字符串空白/浮点格式差异不一定是语义差异,必须落到参数或consumer行为。

9. Gate E — RUNTIME_OPCODE_COVERAGE

release实际出现的每个CSP必须从branch expected sequence逐opcode找到consumer,说明参数来源、执行条件和次序。RUNTIME_OBSTRN/RUNTIME_WRECKS等粗capability只能作目录索引。

例如SY + S(V) + Q + TX必须逐项证明:主symbol、全部sounding glyph、quality symbol、文本/布局均存在,并在正确pass及状态下执行。只画主SY和普通深度text,整个完整branch不可PASS。

runtime kind范围至少包含CA、DEPARE、DEPCNT、SOUNDG、OBSTRN、WRECKS;新kind须加入usage scanner、capability registry、审计与实际执行证据。unknown kind不得因没有映射就静默忽略。

每opcode覆盖记录至少包括opcode、branch_id、实现路径/函数、输入字段、参数映射、order/pass、status、证据及缺失处理。marker字符串存在只能证明代码位置存在,不能证明release所有分支完整。

10. Gate F — REAL_DATA_BRANCH_COVERAGE

完整扫描正式Plan实际release;核对计划jobs、PBF footprint、explicit empty tiles、decode错误及artifact哈希。计数区分source objects、distinct delivery(layer,FID)、presentation与tile occurrences。

branch signature至少包含:source与delivery geometry、class、VALSOU presence/值域、WATLEV、EXPSOU、CATOBS/CATWRK、QUASOU/QUAPOS、TECSOU/STATUS、关联DRVAL1/2及对象身份/geometry、safety contour/depth、isolated结果、scale/display依赖。静态CSP还应有RESTRN/CATREA、CONDTN/CATSLC、LIGHTS相关属性等。

每个实际signature必须唯一映射到上游组合路径,或明确保存候选branch_ids+NOT_PROVEN+缺失字段。候选映射不等于full coverage PASS。允许在source unavailable时完成delivery扫描并将完整源级branch count置null;不得把缺失字段当源属性absent、把null当0,或用最终SY猜原始限制属性。

必须保留未观察到的上游分支。nested procedure不能因没有同名顶层CSP字段就判NOT_OBSERVED。实际出现而没有完整expected/actual覆盖的分支阻止Target Portrayal PASS。

11. Gate G — RESOURCE_DEPENDENCY_EQUIVALENCE

每个branch逐项列SY/AP/LC等资源名,动态SOUNDG家族须按可生成symbol universe展开。检查:

  • 固定上游引用及定义证据;当前CM95 resource universe。
  • metadata/sprite/pattern/line key是否构建,是否被style/runtime过滤掉。
  • resource参数(pivot、mm、颜色表、位图/矢量等)的消费证据。
  • 缺失时fail-closed或fallback路径是否与实际上游对应。

DANGER53等代码引用而缺资源应单独记录。禁止补造fallback把审计改PASS;也不能认为所有“问号fallback”在不同opcode中等价。上游SY/LC/AP fallback必须分别核实,不凭历史contract注释推断。

资源检查的局部PASS与branch总体FAIL/NOT_PROVEN可以同时存在,机器schema必须支持这种分离。

12. Gate H — MARINER_DEPENDENCY_EQUIVALENCE

至少逐项检查safety contour/depth、shallow/deep contour、two_shades、symbolized boundaries、point/boundary table、display category、priority/SCAMIN、display scale;还应包括depth/height units、文本/测深显示、灯描述/航标文本开关、屏幕毫米/缩放、颜色表与碰撞状态。

PBF保留原始稳定事实和presence,不固化随设置变化的最终color、safety contour、sounding family、isolated danger或promotion。reference模式允许明确固定profile,必须与runtime交付区分。

mariner-dependent不能仅等于当前六个水深CSP:RESARE的symbolized boundaries、LIGHTS的height unit与render尺度同样需要依赖证明。静态materialization宣称成立,须证明其输出在全部允许runtime settings下不变。

surrounding max/min scalar若不能保持关联对象geometry、membership与相同选择范围,不足以证明UDWHAZ。有效contour catalog不能仅凭当前viewport已加载线的最小值默认等价于chart catalog。

13. Gate I — RENDER_ORDER_EQUIVALENCE

分别证明同对象多primitive顺序、fill/pattern/line/symbol/text跨pass、initial/current display category与priority、CSP DisplayBase promotion、SCAMIN变化、静态层与runtime overlay、不同对象与symbol/text碰撞顺序。

MapLibre按priority/source-layer/opcode分层不是自动等价于OpenCPN rule execution。canvas overlay在全部style层上方必须提供排序证据;无法证明严格等价时为NOT_PROVEN。已证明缺失/多出的priority或primitive仍为FAIL。

同一设置变更应使用同一snapshot并失效相应cache,不得让DEPARE、DEPCNT、hazard与SOUNDG混用旧/新设置。截图仅作为最后视觉材料,不能替代code/rule/consumer证据。

14. Data Release 与 Target Portrayal 两道独立门槛

14.1 当前生产行为(截至本轮实际代码)

src/cm95pbf/release.py对Builder0.4.11+要求presentation conservation artifact,校验schema、PASS、plan_id和pbf_dir。runtime capability artifact在提供时为硬门槛;未提供时保持NOT_AUDITED,不能称target已审计。

tools/cm95_s52_runtime_capability_audit.py目前检查粗runtime kind、IMPLEMENTED和evidence marker。本标准新增的branch/sequence/opcode/source coverage要求尚不是该工具的已实现功能。

14.2 v2 声明 strict Target Portrayal PASS 的必要条件

  • A–I在明确输入域/target/settings下均有完整PASS证据。
  • source→presentation→delivery invariants PASS。
  • 实际所需的全部runtime consumers完整实现,不能用PREVIEW_ONLY替代。
  • 对应release的resource、branch、sequence、nested、settings、render-order结果绑定同一Plan和PBF;不能复用其他release或缩小AOI的PASS。
  • 无实际出现的FAIL/NOT_IMPLEMENTED/NOT_PROVEN;未观察分支保留观察状态及未来覆盖责任。

Data Release可以继续使用它自己的数据验收结论;本轮审计FAIL不擅自改写既有release manifest,也不声称它证明了portrayal。

15. 机器产物与报告最小合同

JSON至少包含OpenCPN commit/root/hash校验、CM95 HEAD/worktree input hashes、Plan/release绑定、gate statuses、完整branch rows、真实调用图、ordered expected instructions、observed instructions/consumer、opcode coverage、resource dependencies、签名与计数单位、evidence paths/lines、unresolved items、验证方法及限制。

Markdown中每组CSP至少一张表,列为:branch_id、geometry、condition、mariner_dependency、nested_csp、expected_sequence、cm95_python、pbf_or_runtime_facts、style_or_runtime_consumer、real_data_count、status、evidence。

同时回答重复Python/JS决策、已确认不等价、同结构风险、是否建立统一Decision/Runtime Rule IR、runtime必须保留的字段、通用executor与专用renderer边界、scalar hint损失这七项架构问题。

临时分析器只在/tmp等非仓库位置;不新增Jest,不修改产品来制造PASS。本轮正式输出仅v2报告、v2标准和build/audits/cm95_s52_opencpn_code_first_equivalence_v2.json。

16. 历史、已关闭事项和后续阶段

v1 multi-LIGHTS source→PBF修复及正负回归是已记录的历史验收,不能把旧问题继续写成当前必然存在,也不能用旧PASS覆盖本次完整LIGHTS调用/文本/renderer审计。

本轮当前结论见流程对照报告v2:Target Portrayal FAIL;F源级branch覆盖、固定上游资源独立定义与全局renderer环境存在NOT_PROVEN。具体branch内部状态以报告和JSON为准。

统一IR、产品缺陷修复、自动gate实现、全输入域执行回归均为尚未启动的后续阶段。本标准不授权修改已有功能,也不暗示这些后续工作已经完成。