# 24-04 HAL Component Precompile Manifest / Truth-Table Gate 落地蓝图 > 后续状态:阶段 A 已由 `26` 完成,阶段 B-D 已由 `27` 完成。本文保留实施合同;涉及“当前缺失/只记录事件”的段落应结合 `27` 的最终机器 gate 阅读。 ## 定位 本文件落实 `ACC-036/INT-023`:在 `19-04动态加载与预编译Manifest复核.md` 和 `21-04-HAL-Component-Precompile-Manifest实现缺口复核.md` 已确认边界和缺口后,把 `and2`、`or2`、`not`、`mux2`、`scale` 的源码同步、预编译 manifest、实例化、线程执行和 truth-table/formula evidence 收敛为可直接实施的合同。 覆盖 04 条目: - `4.7 and2 组件` - `4.8 or2 组件` - `4.9 not 组件` - `4.10 mux2 组件` - `4.11 scale 组件` - `4.16 loadrt 加载组件` 严格口径:不得在 JS/TS 或项目自有 C/C++ 中手写五个组件公式后宣称 LinuxCNC 源码复用。组件实现必须直接编译 LinuxCNC `.comp` 的生成物,或由可复现工具从 vendored `.comp` 生成最窄适配层;manifest、生成物和 WASM 必须绑定同一上游源码哈希。 ## 本轮实物复核结论 | 检查项 | 当前事实 | 严格结论 | | --- | --- | --- | | 上游源码 | 五个 `.comp` 均存在于 `linuxcnc/src/hal/components/` | P0 来源已确定 | | vendored 源码 | 五个 `.comp` 已抽取到 `wasm-port/vendor/linuxcnc/src/hal/components` | 专项 P1 同步已完成,见 `26` | | source manifest | 两个 manifest 已登记五个 `.comp`,专项 commit/字节/hash gate 已通过 | 1 个非上游 generated fallback 已由独立 manifest 锁定,全量 vendor/overlay gate 通过 | | WASM 构建 | `build_task_hal_wasm.sh` 只编译 task subset、HAL runtime、motion runtime 和 task-HAL wrapper | 五个组件没有进入 WASM object/link | | 导出符号 | `EXPORTED_FUNCTIONS` 不含组件实例化或执行入口 | 无真实 WASM component symbol proof | | `loadrt` | `linuxcnc_hal_runtime.cpp` 仅追加 `loadrt:` event 并返回成功 | 不是实例化证据 | | `addf` | 当前只把函数名登记到 thread | 未绑定可调用函数指针/组件实例 | | servo step | `lchal_step_threads()` 只追加 `call::` event | 未执行组件公式、未更新输出 pin | | Web evidence | 代表配置有原生 `loadrt mux2/scale` 和 `addf` 文本 | 只能证明 LinuxCNC 原生配置使用组件 | 因此,`4.7-4.11` 仍是“待实现预编译执行 gate”,`4.16` 只能保持“预编译 allowlist 条件通过/任意动态加载 Blocked”。 ## LinuxCNC 源码与哈希基线 上游基线 commit: ```text 60597ee0718873d2449058c824262a275e5e4bad ``` | 组件 | 上游源码 | SHA-256 | LinuxCNC 函数语义 | | --- | --- | --- | --- | | `and2` | `src/hal/components/and2.comp` | `29f02d1342bae24d138bbb1387b006b97f592967b8688ccb1c6c0af451cae419` | `out = in0 && in1` | | `or2` | `src/hal/components/or2.comp` | `c27663ce45f9562d7a5dc1b542da50ec2cc60802ef591ee729222002083a3c08` | `out = in0 || in1` | | `not` | `src/hal/components/not.comp` | `9fd9522627db9926d037dc0c116badce7dc880f190c6f8b85c690cbb8b638332` | `out = !in` | | `mux2` | `src/hal/components/mux2.comp` | `b75e3eeb74297d09d13052e812de53a38613ea8287522c371cc2fdaf76be3284` | `sel ? in1 : in0` | | `scale` | `src/hal/components/scale.comp` | `d6830d74fd3462c7b7285a9e0b37cbcd2c53d2243007a198e3f19bfed9817f4f` | `out = in * gain + offset` | 五个组件都声明 `function _` 和 `option period no`。LinuxCNC 原生名称规则、`names=`/`count=` 实例化以及函数注册由 `halcompile` 生成代码负责;Web/WASM 适配不得改变 pin 方向、类型、默认值、实例命名或函数语义。 ## 实施顺序 ### 阶段 A:P1 源码同步闭合 必须先把以下路径加入可复现同步清单: ```text src/hal/components/and2.comp src/hal/components/or2.comp src/hal/components/not.comp src/hal/components/mux2.comp src/hal/components/scale.comp ``` 目标文件必须位于: ```text wasm-port/vendor/linuxcnc/src/hal/components/ ``` 最低 gate: ```bash cd wasm-port ./tools/extract_sources.sh ./tools/verify_vendor_sync.sh sha256sum vendor/linuxcnc/src/hal/components/{and2,or2,not,mux2,scale}.comp ``` 要求:五个 vendored 文件与上游逐字节一致;任何 source hash 变化必须让 manifest gate 失败,不能自动接受新公式。 ### 阶段 B:LinuxCNC 派生生成物 推荐构建路径:使用与锁定基线一致的 LinuxCNC `halcompile --preprocess` 生成 C,再通过最窄 RTAPI/HAL shim 编译到 task-HAL WASM。若源树中只有 `halcompile.g` 而没有可执行的生成器,必须先在构建工具链中生成/定位 LinuxCNC `halcompile`,不能用正则截取 `FUNCTION(_)` 或人工复制公式替代。 建议产物: ```text wasm-port/build/generated/hal-components/and2.c wasm-port/build/generated/hal-components/or2.c wasm-port/build/generated/hal-components/not.c wasm-port/build/generated/hal-components/mux2.c wasm-port/build/generated/hal-components/scale.c wasm-port/build/generated/hal-components/generation-report.json ``` `generation-report.json` 最少包含: | 字段 | 要求 | | --- | --- | | `upstreamCommit` | 固定为锁定 commit | | `generator` | LinuxCNC `halcompile` 路径/版本 | | `sourcePath` | vendored `.comp` 路径 | | `sourceSha256` | 必须等于本文件基线 | | `generatedPath` | 生成 C 路径 | | `generatedSha256` | 用于增量构建和漂移检查 | | `commandFingerprint` | 生成命令和参数摘要 | 生成过程必须增量执行:源码哈希、生成器哈希和命令指纹未变化时不得无条件重生成或重编译。 ### 阶段 C:预编译 Manifest 建议文件: ```text wasm-port/runtime/manifests/hal_component_precompile_manifest.json ``` 顶层最小字段: | 字段 | 规则 | | --- | --- | | `apiName` | 固定为 `hal_component_precompile_manifest` | | `schemaVersion` | 固定为 `1` | | `upstreamCommit` | 与 `tools/upstream-baseline.txt` 一致 | | `dynamicLoadrtSupported` | 固定为 `false` | | `unknownComponentPolicy` | 固定为 `blocked` | | `components[]` | 必须恰好覆盖当前 allowlist | `components[]` 每项最小字段: | 字段 | 规则 | | --- | --- | | `component` | `and2`、`or2`、`not`、`mux2`、`scale` | | `linuxcncSource` | vendored `.comp` 相对路径 | | `sourceSha256` | 与 P0/P1 基线一致 | | `generatedSource` | LinuxCNC `halcompile` 派生 C | | `wasmFactorySymbol` | 创建 `names=`/`count=` 实例的 C ABI | | `wasmStepSymbol` | 组件函数执行入口,或绑定到 runtime function registry 的 symbol | | `pins[]` | 名称、方向、HAL type、默认值 | | `functions[]` | LinuxCNC HAL function 名、`usesFp`、period policy | | `loadrtArgs` | 明确支持的 `names=`、`count=` 子集和互斥规则 | | `tests[]` | manifest、truth-table/formula、thread/net gate 路径 | ### 阶段 D:`loadrt` / `addf` / servo-step 执行链 运行时必须形成以下调用链: ```text HAL text loadrt -> allowlist lookup -> parse names=/count= -> call precompiled factory -> create LinuxCNC-compatible pins/functions -> register callable function entry HAL text addf -> resolve registered function -> attach callable entry to virtual thread lchal_step_threads -> invoke callable entry in thread order -> update output pins -> propagate connected signals -> emit execution evidence ``` 失败规则: - 未知组件:返回 blocked,不得仅记录 event 后成功。 - manifest 中有组件但 WASM symbol 缺失:启动失败。 - `names=` 与 `count=` 同时出现:按 LinuxCNC 行为拒绝。 - 重复实例名、pin 名冲突、未知 `addf` function:返回错误。 - thread step 只写 `call:` event 但没有实际输出变化:gate 失败。 ## Truth-Table / Formula Evidence 建议 evidence: ```text wasm-port/build/evidence/hal-component-truth-table-evidence.json ``` 顶层最小字段: | 字段 | 规则 | | --- | --- | | `apiName` | `hal_component_truth_table_evidence` | | `schemaVersion` | `1` | | `upstreamCommit` | 锁定基线 | | `manifestSha256` | 绑定实际 manifest | | `runtimeSource` | `linuxcnc-derived-precompiled-hal-component` | | `components[]` | 五个组件全部出现 | | `integrity.complete` | 所有向量、thread/net 和 blocked case 通过时为 `true` | 每个测试向量必须记录 `instance`、`inputs`、`expected`、`actual`、`threadCycle`、`outputPin`、`connectedSignal`、`passed`。最小向量: | 组件 | 最小覆盖 | | --- | --- | | `and2` | 4 组 bit 组合 | | `or2` | 4 组 bit 组合 | | `not` | 2 组 bit 输入 | | `mux2` | `sel=false`、`sel=true`,并使用不相等 float 输入 | | `scale` | 至少 3 组,覆盖正 gain、负 gain、非零 offset,误差容限显式记录 | 每个组件至少一个向量必须通过真实 `loadrt -> setp/net -> addf -> lchal_step_threads -> snapshot` 路径,不能只直接调用测试 helper。 ## 建议 Gate ### `wasm-port` 建议新增: ```text wasm-port/tools/generate_hal_component_sources.sh wasm-port/tools/verify_hal_component_source_sync.sh wasm-port/tests/wasm/node/verify_hal_component_precompile_manifest.mjs wasm-port/tests/wasm/node/verify_hal_component_truth_tables.mjs wasm-port/tests/wasm/node/verify_hal_component_thread_net_execution.mjs ``` 命令和通过输出: ```bash cd wasm-port ./tools/verify_hal_component_source_sync.sh node tests/wasm/node/verify_hal_component_precompile_manifest.mjs node tests/wasm/node/verify_hal_component_truth_tables.mjs node tests/wasm/node/verify_hal_component_thread_net_execution.mjs ``` ```text hal_component_source_sync=ok hal_component_precompile_manifest=ok hal_component_truth_tables=ok hal_component_thread_net_execution=ok unknown_loadrt_component_blocked=ok ``` ### `web-rtcp-5axis-xyzbc-trt-sim-plan` 目标 Web 项目不应再实现一套组件公式。它应消费 `wasm-port` task-HAL runtime 输出,并在 evidence 中引用: ```text halComponentManifest halComponentExecution halComponentBlockedCases ``` 代表 profile 至少要证明 `xyzac-trt_cmds.hal` 中 `mux2` 和 `scale` 的实例名、pin、`addf` 顺序和输出来自相同 WASM runtime。`compare-xyzbc-trt-evidence.json` 需记录 native HAL 配置声明与 Web/WASM 组件实例/执行结果的对应关系,但不能用配置文本相等替代运行结果。 ## 04 严格状态与晋级条件 | 04 项 | 当前状态 | 晋级条件 | | --- | --- | --- | | `4.7 and2` | P1 已完成,预编译执行 gate 待补 | manifest、WASM symbol、4 组 truth table、thread/net proof | | `4.8 or2` | P1 已完成,预编译执行 gate 待补 | manifest、WASM symbol、4 组 truth table、thread/net proof | | `4.9 not` | P1 已完成,预编译执行 gate 待补 | manifest、WASM symbol、2 组 truth table、thread/net proof | | `4.10 mux2` | P1 已完成,预编译执行 gate 待补 | `sel` 两路、`names=` 实例化、代表 XYZAC HAL 配置、thread/net proof | | `4.11 scale` | P1 已完成,预编译执行 gate 待补 | 公式向量、浮点容差、代表 `rpm_rps` 实例、thread/net proof | | `4.16 loadrt` | 预编译 allowlist 条件通过/动态加载 Blocked | allowlist 组件真实实例化;未知组件 blocked;仍不得宣称任意 `.so` 动态加载 | ## 与现有文件的关系 - `19-04动态加载与预编译Manifest复核.md`:定义动态加载和预编译边界。 - `21-04-HAL-Component-Precompile-Manifest实现缺口复核.md`:确认当前实现缺口。 - 本文件:补充 source sync、哈希、生成物、manifest、runtime 调用链、evidence 和 gate 的落地合同。 - `26-04-HAL-Component-P1源码同步与哈希Gate实施记录.md`:记录阶段 A 已实施、专项 gate 已通过以及严格 upstream/生成 overlay 分层。 - 实际实现完成后,必须把运行输出回填到 `05-验收证据.md`,再更新 `14` 中 `4.7-4.11/4.16` 的状态。 ## 结论 `ACC-036/INT-023` 已把 HAL component precompile 从“需要 manifest/truth-table”细化为可执行实施合同;`ACC-038/INT-025` 已完成五个 `.comp` 的专项 P1 同步/hash 和全量 vendor/overlay gate。后续仍须完成 LinuxCNC 派生生成、预编译 symbol、真实 `loadrt/addf/servo-step` 调用和结构化 truth-table/formula evidence,04 的 `4.7-4.11` 才能晋级;任意运行时动态 `loadrt` 仍保持 Blocked。 ## 后续状态 剩余实施合同已由 `ACC-039/INT-026` 闭合,五组件具备可复现生成、manifest、真实预编译 factory/thread/net 执行和结构化 truth-table/formula evidence。当前状态见 `27-04-HAL-Component-Precompile-Runtime-Gate实施记录.md`;固定 allowlist 条件通过,任意运行时动态 `loadrt` 继续 Blocked。