1184 lines
63 KiB
Markdown
1184 lines
63 KiB
Markdown
# 06-决策记录
|
||
|
||
## D-046:task status JSON 不再保留旧顶层字段兼容视图
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`lctask_read_status_json()` 只通过 `emcStatus` 导出 task/motion/io/top 状态,不再输出 `taskTopLevelStatus`、`rcsStatus`、顶层 `task`、`servoCycle`、顶层 `motionStatus`。
|
||
|
||
本决策取代 D-044 中“既有旧字段保留为兼容视图”的部分;D-044 中“status JSON 对标 LinuxCNC status buffer、JSON 不能成为事实源、read status 只读”的部分继续有效。
|
||
|
||
### 理由
|
||
|
||
上层项目已经迁移到 `emcStatus` 契约。继续在源头输出旧字段会扩大状态表面,导致 SDK/UI 继续依赖旧字段,并让后续 LinuxCNC `EMC_STAT` 对标和契约测试同时维护两套入口。
|
||
|
||
### 影响
|
||
|
||
- `status_json()` 移除旧顶层字段输出。
|
||
- `emcStatus.task` 和 `emcStatus.motion` 补齐旧视图中仍需要的字段。
|
||
- WASM、SDK、state matrix 和 status contract 测试均对旧顶层字段做负向断言。
|
||
- 后续新增字段只能进入 `emcStatus` 或底层 C/C++ status buffer,不新增旧字段兼容视图。
|
||
|
||
## D-045:SJ-1 到 SJ-5 必须进入任务矩阵并由 contract gate 固定
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`11-WASM核心状态机边界与后续完善路线.md` 和 `12-status-json-LinuxCNC对标方案.md` 中的 SJ-1 到 SJ-5 是实际后续实现任务,不再只作为“未来路线”保留。将 SJ-1 到 SJ-5 分别补入 `04-任务矩阵.md` 的 T-051 到 T-055,并以 `tools/verify_task_status_json_contract.sh` 固定 status JSON schema。
|
||
|
||
### 理由
|
||
|
||
上一轮只检查任务矩阵,导致 `11` 和 `12` 中已经写明目标和验收标准的任务没有被发现。后续只要文档中出现可执行实现项,就必须同步进入任务矩阵、验收证据和 gate,否则“矩阵闭合”没有实际意义。
|
||
|
||
### 影响
|
||
|
||
- T-051 到 T-055 已闭合,覆盖 `emcStatus.motion.traj`、task line 字段、axis/joint 数组、IO aux/tool/coolant 和 status JSON contract gate。
|
||
- `tools/verify_task_full_closure.sh` 纳入 `tools/verify_task_status_json_contract.sh`。
|
||
- source reuse、drift、compatibility 和 working closure gate 均检查 T-051 到 T-055。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-044:status JSON 对标 LinuxCNC status buffer,而不是替代状态机
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
后续在 WASM 中解决 `status JSON` 时,对标 LinuxCNC 的 `EMC_STAT` / status buffer 模型:C/C++ 侧维护 `StandaloneEmcStatus` 或后续 `EMC_STAT` 等价容器,`write_status_snapshot()` 写入最后一次 status buffer,`lctask_read_status_json()` 只把该 buffer 序列化为 JSON。
|
||
|
||
新增 LinuxCNC 对标字段默认进入 `emcStatus` JSON 对象。既有 `task`、`motionStatus`、`rcsStatus`、`taskTopLevelStatus` 等字段保留为兼容视图,但必须从同一 C/C++ status buffer 导出。
|
||
|
||
### 理由
|
||
|
||
上游 LinuxCNC GUI 读取的是 status channel 中的 `EMC_STAT` 快照,而不是在 GUI 中重建 task/motion 状态机。WASM/browser 环境不能直接暴露 native NML/CMS channel,因此用 JSON 作为外部传输格式是合理的;但 JSON 不能成为语义事实源,否则会重新引入 JS/JSON 状态机并偏离 LinuxCNC 对标目标。
|
||
|
||
### 影响
|
||
|
||
- 新增 `12-status-json-LinuxCNC对标方案.md`。
|
||
- 后续 status 字段扩展按 SJ-1 到 SJ-5 分批推进。
|
||
- `lctask_read_status_json()` 必须保持只读,不推进 cycle、不重新读取 motion、不消费 command。
|
||
- 后续应新增 `tools/verify_task_status_json_contract.sh` 并纳入 full closure gate。
|
||
- 当前 readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-043:后续 WASM 程序定位为核心状态机实现载体
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
后续完善 `wasm-port` 程序时,WASM/C++ 侧作为核心状态机实现的运行载体,承载 LinuxCNC 语义复用、task/motion 状态机、周期调度、motion snapshot、状态聚合、command read/plan/execute 和 `StandaloneEmcStatus`。
|
||
|
||
JS/SDK 只承担加载 WASM、传命令、读状态、Emscripten FS/OPFS 和浏览器/Node 边界。JSON 只作为外部通信格式,例如 command JSON 和 status JSON,不作为核心状态机事实源。
|
||
|
||
### 理由
|
||
|
||
JSON 适合跨 host/browser 边界传输数据,但不适合保存和推进 task/motion 状态机。核心状态应由 C/C++ 结构体、枚举、队列和周期函数维护,并尽量复用 vendored LinuxCNC source。这样可以避免 JS/JSON 重新实现 CNC 语义,也符合 `wasm-port/AGENTS.md` 中“核心 CNC 逻辑编译到 WASM、前端只做 web 技术实现”的方向。
|
||
|
||
### 影响
|
||
|
||
- 新增 `11-WASM核心状态机边界与后续完善路线.md` 作为后续任务入口。
|
||
- 后续新增状态字段应先进入 `StandaloneEmcStatus` 或后续 `EMC_STAT` 等价容器,再导出到 status JSON。
|
||
- 后续新增 command 应先通过 JSON/C ABI 入队,再由 `lctask_run_cycles()` 的 command read/plan/execute 阶段消费。
|
||
- 当前 T-001 到 T-049 闭合状态不变;后续代码任务必须先补入 `04-任务矩阵.md`。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-042:T-049 建立 task-HAL 全量闭合验证入口
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
新增 `tools/verify_task_full_closure.sh` 作为 task-HAL 对标工作的统一闭合入口。该脚本负责构建 task-HAL WASM,并串行运行核心 runtime smoke、SDK smoke、state matrix、motion/HAL sync、T-007 `StandaloneEmcStatus`、T-046 no-JSON 主路径、T-047/T-048 working closure、source reuse/drift docs 和 readiness contract gates。
|
||
|
||
### 理由
|
||
|
||
T-048 已将 working closure 纳入全局文档一致性验证,但最终验收仍需要人工记住多条命令。建立 full closure gate 可以把当前闭合状态固化成单一入口,降低后续遗漏某个关键 smoke 或文档 gate 的风险。
|
||
|
||
### 影响
|
||
|
||
- T-049 可闭合,当前任务矩阵继续保持全部完成。
|
||
- 后续 task-HAL 对标回归可优先运行 `./tools/verify_task_full_closure.sh`。
|
||
- 不改变 runtime、WASM ABI、SDK 或 readiness。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-041:T-048 将 working closure gate 纳入全局文档一致性 gate
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-048 将 `tools/verify_task_working_closure.sh` 记录到 `docs/source-reuse-map.md` 和 `docs/compatibility-validation.md`,并让 `tools/verify_task_source_reuse_drift_docs.sh` 检查该 gate、对应 compatibility 文案和 T-048 矩阵状态。
|
||
|
||
### 理由
|
||
|
||
T-047 已经建立 working closure gate,但如果该 gate 只存在于 working 文档中,总文档一致性检查无法发现后续 source reuse / compatibility 文档漏记闭合 gate 的漂移。T-048 将 closure gate 纳入全局文档验证链,使“矩阵闭合、后续先补任务”的规则不只靠人工记忆维护。
|
||
|
||
### 影响
|
||
|
||
- T-048 可闭合,当前任务矩阵继续保持全部完成。
|
||
- `verify_task_source_reuse_drift_docs.sh` 新增 working closure gate 检查。
|
||
- 不改变 runtime、WASM ABI、SDK 或 readiness。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-040:T-047 将 working 索引收口为“矩阵闭合、后续先补任务”
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-047 不新增 runtime 行为,只收口 working 文档索引和闭合 gate。`working/README.md`、`01-项目功能内容.md` 和 `09-emc_nml复用评估.md` 的当前状态描述更新为 T-007/T-046 后的事实:`StandaloneEmcStatus` 已建立,task status 来自周期 snapshot/status write,RUN 主路径不依赖 host JSON motion plan。
|
||
|
||
新增 `tools/verify_task_working_closure.sh`,固定当前矩阵所有任务完成、下一条优先任务为“无”、无 `待办`/`进行中`/`阻塞` 任务,以及 working 索引文档包含当前闭合口径。
|
||
|
||
### 理由
|
||
|
||
T-007 完成后,原工作目录中的索引文档仍保留“当前缺少 EMC_STAT 容器”“motion 状态只在 status JSON 拼接”等历史描述。继续对标前必须避免 working 文档把已完成的任务重新描述成现状缺口。后续扩展应先新增矩阵任务、验收标准和 gate,再实施变更。
|
||
|
||
### 影响
|
||
|
||
- T-047 可闭合,当前任务矩阵继续保持全部完成。
|
||
- `verify_task_working_closure.sh` 成为 working 索引闭合 gate。
|
||
- 不改变 `linuxcnc_task_hal_wasm.cpp`、WASM ABI、SDK 或 runtime readiness。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-039:T-007 采用 `StandaloneEmcStatus` 作为当前阶段 `EMC_STAT` 等价容器
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-007 在 `linuxcnc_task_hal_wasm.cpp` 内建立 `StandaloneEmcStatus`,包含 `StandaloneEmcTaskStatus`、`StandaloneEmcMotionStatus` 和 `StandaloneEmcIoStatus`。该容器集中保存当前 WASM task/motion/io/top 所需的 `EMC_STAT` 等价字段。
|
||
|
||
`write_status_snapshot()` 在写入 `status_buffer` 前调用 `sync_standalone_emc_status()`,把 task 执行状态、motion snapshot、IO error/estop latch 和 RCS 聚合状态同步到容器。`status_json()` 从该容器导出新增 `emcStatus`,并让兼容字段 `taskTopLevelStatus`、`rcsStatus`、`task` 和 `motionStatus` 读取同一份容器状态。
|
||
|
||
### 理由
|
||
|
||
直接引入完整上游 `emc_nml.hh` 仍会拉入 NML/CMS、消息序列化、RS274/canon/tool-table 等依赖,超出当前 runtime-edge adapter 的边界。T-029 已记录分阶段 `StandaloneEmcStatus` / typedef 路线,因此 T-007 先把必需字段集中到明确容器,减少 JSON status 拼接时直接读取分散 runtime 字段的漂移。
|
||
|
||
### 影响
|
||
|
||
- T-007 可闭合,当前任务矩阵全部完成。
|
||
- status JSON 新增 `statusSource=StandaloneEmcStatus` 和 `emcStatus`。
|
||
- `verify_task_hal_wasm.sh` 新增 `standalone_emc_status_container=ok`。
|
||
- `verify_task_hal_sdk.sh` 新增 `task_hal_sdk_standalone_emc_status=ok`。
|
||
- `verify_task_state_matrix.mjs` 新增 `standalone_emc_status_matrix=ok`。
|
||
- 新增 `tools/verify_task_standalone_emc_status.sh` 固定 T-007 结构、测试、文档和矩阵状态。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-038:T-046 主 RUN 路径移除 JSON motion plan 依赖,保留 timed-plan 兼容入口
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-046 将默认 RUN 文件验证路径切换为 staged program 驱动:`emcTaskPlanRead()` 读取已打开程序行,`emcTaskPlanCommand()` 生成 command evidence,`emcTaskPlanExecute()` 进入 `emccanon.cc` command envelope,并通过 `taskintf.cc` issue 到 motion runtime。主 smoke 和默认 SDK/status 场景不再预调用 `lctask_load_program_motion_plan_json()`。
|
||
|
||
`loadProgramMotionPlan()` 与 wrapper 内的 `lctask_load_program_motion_plan_json()` 暂不删除,降级为 timed motion plan 兼容/调试入口。该入口只在显式 compatibility 场景中验证,不作为主 RUN 路径的验收基础。
|
||
|
||
### 理由
|
||
|
||
T-040 已引入 `emctask.cc` plan read/execute 子集,T-041 到 T-045 已逐步把 canon init、straight motion、dwell/path-control、spindle/tool 和 motion output 收敛到 `emccanon.cc` evidence。继续让主 smoke 依赖 host JSON motion plan 会掩盖这些 native-like staged-program 边界;因此 T-046 要把默认路径改为程序文本读取和 command execute。
|
||
|
||
同时,timed motion plan 对现有 SDK 用户和调试场景仍有价值,直接删除会扩大兼容风险。保留显式兼容 gate 可以让后续 T-007/T-008 在建立 `EMC_STAT` 和 interpreter 状态机时继续观察两条路径差异。
|
||
|
||
### 影响
|
||
|
||
- T-046 可闭合,任务矩阵下一条推进到 T-007。
|
||
- `verify_task_hal_wasm.sh` 新增 `task_hal_no_json_main_path_status=ok`,且主测试文件不再包含 `lctask_load_program_motion_plan_json()`。
|
||
- `verify_task_hal_sdk.sh` 将 timed plan 输出改为 `task_hal_timed_motion_plan_compat=ok`。
|
||
- `verify_task_state_matrix.mjs` 默认 `loadPlan=false`,新增显式 JSON timed-plan 兼容场景。
|
||
- 新增 `tools/verify_task_no_json_motion_plan_main_path.sh` 固定 T-046 主路径、兼容入口和矩阵状态。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-037:T-045 motion output/switchkins 采用 canon output evidence 到 taskintf AOUT 边界
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-045 将 `SET_MOTION_OUTPUT_BIT()`、`CLEAR_MOTION_OUTPUT_BIT()`、`SET_AUX_OUTPUT_BIT()`、`CLEAR_AUX_OUTPUT_BIT()`、`SET_MOTION_OUTPUT_VALUE()`、`SET_AUX_OUTPUT_VALUE()` 和 `WAIT()` 纳入 `emccanon_wasm_subset`。subset 返回 `LcEmcCanonSubsetOutputCommand`,wrapper 将这些 command 记录为 `EMC_MOTION_SET_DOUT` / `EMC_MOTION_SET_AOUT` / `EMC_AUX_INPUT_WAIT` / `interp_list` evidence。
|
||
|
||
`linuxcnc_task_hal_wasm.cpp` 删除 MDI 中旧的 `mdi.find("M428/M429/M430")` 字符串 special-case。M428、M429、M430 现在先进入 canon `SET_AUX_OUTPUT_VALUE()` evidence,再桥接到既有 `taskintf.cc` `emcMotionSetAout()` / `lcmot_write_aout()` 路径,维持当前 switchkins HAL 同步行为。
|
||
|
||
### 理由
|
||
|
||
上游 `emccanon.cc` 的 output/wait callbacks 负责生成 `EMC_MOTION_SET_DOUT`、`EMC_MOTION_SET_AOUT` 和 `EMC_AUX_INPUT_WAIT` 并 append 到 `interp_list`。当前 WASM runtime 已有 `emcMotionSetAout()` 到 `lcmot_write_aout()` 的结构化 switchkins 路径,因此 T-045 只将 M428-M430 入口迁移到 canon output evidence,不扩展或伪造完整数字 IO、模拟 IO wait、motion queue ownership 或 NML transport。
|
||
|
||
### 影响
|
||
|
||
- T-045 可闭合,任务矩阵下一条推进到 T-046。
|
||
- `verify_task_hal_wasm.sh` 新增 `emccanon_motion_output_status=ok`。
|
||
- 新增 `tools/verify_task_emccanon_motion_output.sh` 固定 T-045 上游锚点、subset API、wrapper status、旧 special-case 移除和矩阵状态。
|
||
- `verify_task_hal_sdk.mjs` 改为断言新的 canon output 事件。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-036:T-044 spindle/tool 采用 `emccanon.cc` 窄 command envelope evidence
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-044 将 `SET_SPINDLE_SPEED()`、`START_SPINDLE_CLOCKWISE()`、`START_SPINDLE_COUNTERCLOCKWISE()`、`STOP_SPINDLE_TURNING()`、`SELECT_TOOL()`、`CHANGE_TOOL()`、`CHANGE_TOOL_NUMBER()` 和 `RELOAD_TOOLDATA()` 纳入 `emccanon_wasm_subset`。subset 返回 spindle/tool command envelope,wrapper 将这些 command 记录为 `EMC_SPINDLE_*` / `EMC_TOOL_*` / `interp_list` evidence。
|
||
|
||
`linuxcnc_task_hal_wasm.cpp` 在 MDI 和 staged program line 进入 dwell/path-control 与 straight motion 前识别 `S...`、精确 `M3/M4/M5`、`T...`、精确 `M6` 和 `M61 Q...`。精确 M-code 解析用于避免 `M428/M429/M430` 这类 switchkins special-case 被误判为 `M4`。status JSON 新增 `spindleCommandCount`、`spindleAppendCount`、`lastSpindleCommand`、`lastSpindle`、`lastSpindleSpeed`、`lastSpindleWait`、`toolCommandCount`、`toolAppendCount`、`lastToolCommand`、`lastTool` 和 `spindleToolAnchors`。
|
||
|
||
### 理由
|
||
|
||
上游 spindle/tool canonical callbacks 构造 `EMC_SPINDLE_SPEED`、`EMC_SPINDLE_ON`、`EMC_SPINDLE_OFF`、`EMC_TOOL_PREPARE`、`EMC_TOOL_LOAD`、`EMC_TOOL_SET_NUMBER`、`EMC_TOOL_LOAD_TOOL_TABLE` 并 append 到 `interp_list`。T-044 先迁移可观测 command envelope 和 anchor evidence,避免把 full native spindle control、tool DB process、IO side effects、queue ownership 和 NML transport 混入当前 WASM runtime-edge adapter。
|
||
|
||
### 影响
|
||
|
||
- T-044 可闭合,任务矩阵下一条推进到 T-045。
|
||
- `verify_task_hal_wasm.sh` 新增 `emccanon_spindle_tool_status=ok`。
|
||
- 新增 `tools/verify_task_emccanon_spindle_tool.sh` 固定 T-044 上游锚点、subset API、wrapper status 和矩阵状态。
|
||
- `docs/source-reuse-map.md`、`docs/drift-report.md`、`docs/compatibility-validation.md` 和 `tools/verify_task_source_reuse_drift_docs.sh` 记录 T-044 spindle/tool 映射。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-035:T-043 dwell/path-control 采用 `emccanon.cc` 窄 interp-list evidence
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-043 将 `DWELL()` 和 `SET_MOTION_CONTROL_MODE()` 纳入 `emccanon_wasm_subset`。`lc_emccanon_subset_dwell()` 返回 `LcEmcCanonSubsetDelay`,用于记录 `EMC_TRAJ_DELAY` / `interp_list` evidence;`lc_emccanon_subset_set_motion_control_mode()` 返回 `LcEmcCanonSubsetTermCond`,用于记录 `EMC_TRAJ_SET_TERM_COND` / `interp_list` evidence。
|
||
|
||
`linuxcnc_task_hal_wasm.cpp` 在 MDI 和 staged program line 进入 straight motion 前识别 `G4`、`G61`、`G61.1`、`G64`,将 dwell 和 path-control 作为 canon non-motion command 记录到 `emccanonSourceReuse`,不发 motion command。status JSON 新增 `dwellCount`、`delayAppendCount`、`lastDwellSeconds`、`pathControlCount`、`termCondAppendCount`、`lastPathMode`、`lastTermCondition`、`lastPathTolerance`、`dwellPathControlAnchors`。
|
||
|
||
### 理由
|
||
|
||
上游 `DWELL()` 生成 `EMC_TRAJ_DELAY` 并 append 到 `interp_list`;`SET_MOTION_CONTROL_MODE()` 生成 `EMC_TRAJ_SET_TERM_COND` 并 append 到 `interp_list`。T-043 先迁移可观测的 command envelope 和状态证据,避免把 full native blend planner、canon tag、queue ownership 和 NML transport 一次性引入。
|
||
|
||
### 影响
|
||
|
||
- T-043 可闭合,任务矩阵下一条推进到 T-044。
|
||
- `verify_task_hal_wasm.sh` 新增 `emccanon_dwell_path_control_status=ok`。
|
||
- 新增 `tools/verify_task_emccanon_dwell_path_control.sh` 固定 T-043 上游锚点、subset API、wrapper status 和矩阵状态。
|
||
- `docs/source-reuse-map.md`、`docs/drift-report.md`、`docs/compatibility-validation.md` 和 `tools/verify_task_source_reuse_drift_docs.sh` 记录 T-043 dwell/path-control 映射。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-034:T-042 straight traverse/feed 采用 `emccanon.cc` 窄 linear-move envelope
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-042 将 `generate_fast_move()`、`generate_move()`、`STRAIGHT_TRAVERSE()`、`STRAIGHT_FEED()` 到 `EMC_TRAJ_LINEAR_MOVE` / `interp_list` 的关系固定在 `emccanon_wasm_subset` 和 task-HAL status evidence 中。`lc_emccanon_subset_straight_traverse()` 与 `lc_emccanon_subset_straight_feed()` 继续返回 `LcEmcCanonSubsetLinearMove`,wrapper 在 `taskintf_command_from_canon()` 处统一记录 straight traverse/feed 计数、linear move append 计数、最后 line、最后 canonical motion type、最后 interp_list command 和 `straightMotionAnchors`。
|
||
|
||
该边界仍不实现完整 LinuxCNC canon offsets、tag、feed mode、acc/jerk、NURBS 或 NML queue ownership;生成的 linear move envelope 随后通过既有 `taskintf.cc` `emcTrajLinearMove()` / `lcmot_write_linear_move()` 结构化 motion 边界进入 motion runtime。
|
||
|
||
### 理由
|
||
|
||
T-041 已迁入 canon 初始化、finish、reset、单位和 endpoint getter,但 straight traverse/feed 的 `interp_list` evidence 仍只通过泛化 issueCount 间接体现。T-042 把 `EMC_TRAJ_LINEAR_MOVE` 和 `interp_list` append 作为可观测 status 字段固定下来,使后续 T-043/T-044/T-045 可以继续迁移 dwell、path-control、spindle/tool 和 motion output,而不混淆 full native canon promotion。
|
||
|
||
### 影响
|
||
|
||
- T-042 可闭合,任务矩阵下一条推进到 T-043。
|
||
- `verify_task_hal_wasm.sh` 新增 `emccanon_straight_motion_status=ok`。
|
||
- 新增 `tools/verify_task_emccanon_straight_motion.sh` 固定 T-042 上游锚点、subset API、wrapper status 和矩阵状态。
|
||
- `emccanonSourceReuse` 新增 `straightTraverseCount`、`straightFeedCount`、`linearMoveAppendCount`、`lastLinearMoveLine`、`lastLinearMoveType`、`lastInterpListCommand`、`straightMotionAnchors`。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-033:T-041 canon init/finish/unit/endpoint 采用 `emccanon.cc` 窄状态子集
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-041 将 `INIT_CANON()`、`ON_RESET()`、`FINISH()`、`USE_LENGTH_UNITS()`、`GET_EXTERNAL_LENGTH_UNITS()`、`GET_EXTERNAL_ANGLE_UNITS()` 和 `GET_EXTERNAL_POSITION*()` 纳入 `emccanon_wasm_subset`,通过 `LcEmcCanonSubsetState` 保存 initialized、finish/reset 计数、长度/角度单位和 external endpoint。
|
||
|
||
`linuxcnc_task_hal_wasm.cpp` 在 session init、motion update、plan reset、canon move issue 路径调用该 subset,并将 `emccanonSourceReuse` status JSON 扩展为 `initCount`、`finishCount`、`resetCount`、`unitSetCount`、`positionGetCount`、`endpointUpdateCount`、`lengthUnits`、`externalLengthUnits`、`externalAngleUnits`、`endpoint` 和 `initFinishUnitAnchors`。该状态只作为 deterministic Web simulation evidence,不提升 full native interpreter/canon ownership。
|
||
|
||
### 理由
|
||
|
||
T-040 已让 staged program line 进入 `interp_list`/taskintf issue 等价路径,但 canon 初始化、finish、reset、单位和 endpoint getter 仍由 wrapper 自有字段表达。上游 `emccanon.cc` 中这些函数是 interpreter/canon 状态与 `EMC_STAT` 可观测位置/单位之间的基础边界,先迁入窄 subset 可以为 T-042 的 `STRAIGHT_TRAVERSE()`/`STRAIGHT_FEED()` motion command 继续收敛状态来源。
|
||
|
||
### 影响
|
||
|
||
- T-041 可闭合,任务矩阵下一条推进到 T-042。
|
||
- `verify_task_hal_wasm.sh` 新增 `emccanon_init_finish_unit_status=ok`。
|
||
- 新增 `tools/verify_task_emccanon_init_finish_unit.sh` 固定 T-041 上游锚点、subset API、wrapper status 和矩阵状态。
|
||
- `docs/source-reuse-map.md`、`docs/drift-report.md`、`docs/compatibility-validation.md` 和 `tools/verify_task_source_reuse_drift_docs.sh` 记录 T-041 canon init/finish/unit/endpoint 映射。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-032:T-040 plan read/execute 接管 staged program 主路径
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-040 将 `emcTaskPlanRead()`、`emcTaskPlanExecute()`、`emcTaskPlanLine()`、`emcTaskPlanLevel()`、`emcTaskPlanCommand()` 纳入 `emctask_wasm_subset`,并通过 `LcEmcTaskSubsetPlanIoResult` 返回 read/execute/line/level/command 与 `interp_list` append 证据。
|
||
|
||
`EMC_TASK_PLAN_RUN` 不再要求 host 预先调用 `lctask_load_program_motion_plan_json()`;只要 staged FS 中已有 open program,task cycle 可通过 PlanRead/Command/Execute 读取 staged program lines,再映射到现有 `emccanon` straight motion 和 `taskintf` structured motion issue 路径。为了避免 T-039 的 wait flag 阻塞 T-040 read,RUN 起点不再立即 set-wait;wait flag 改为在 staged program 行读完后记录并清理,表达上游 execute-finish 后等待 outstanding work 的窄语义。
|
||
|
||
完整 LinuxCNC interpreter、subroutine call stack、完整 `interp_list` 命令类型和 canon unit/endpoint 状态仍留给 T-041 之后继续迁移;`lctask_load_program_motion_plan_json()` 暂保留为 timed-plan 兼容入口,后续 T-046 再降级或移除。
|
||
|
||
### 理由
|
||
|
||
T-039 已把 plan open/wait/synch/reset 状态迁入 subset,但 RUN 主路径仍依赖 host JSON motion plan。上游 `emctaskmain.cc` 的 readahead loop 是 `PlanRead -> PlanLine/Command -> PlanExecute -> interp_list`;T-040 先建立这个窄边界,使 staged program 可直接驱动 motion issuing,不再把 JSON motion plan 作为 RUN 的必要条件。
|
||
|
||
### 影响
|
||
|
||
- T-040 可闭合。
|
||
- status JSON 的 `emctaskSourceReuse` 新增 `planReadCount`、`planExecuteCount`、`planLineCount`、`planLevelCount`、`planCommandCount`、`interpListAppendCount`、`planReadExecuteAnchors` 等证据字段。
|
||
- `verify_task_hal_wasm.sh` 新增 no-json staged program RUN smoke,输出 `emctask_plan_read_execute_status=ok`。
|
||
- `verify_task_state_matrix.mjs` 将旧的 `INTERPRETER_PLAN_REQUIRED` JSON-plan gate 调整为 staged program 可执行。
|
||
- 新增 `tools/verify_task_emctask_plan_read_execute.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-031:T-039 plan wait/open/synch/reset 采用 `emctask.cc` 窄 plan-result 子集
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-039 将 `emcTaskPlanSetWait()`、`emcTaskPlanIsWait()`、`emcTaskPlanClearWait()`、`emcTaskPlanSynch()`、`emcTaskPlanOpen()`、`emcTaskPlanClose()`、`emcTaskPlanReset()` 纳入 `emctask_wasm_subset`,并通过 `LcEmcTaskSubsetPlanState` / `LcEmcTaskSubsetPlanResult` 表达 plan wait flag、taskplanopen、行号清零、synch、close、reset 等窄语义。
|
||
|
||
staged FS 和 program text 仍由 WASM wrapper 管理;subset 只接收“文件是否已 staged”的布尔边界,并返回与上游 `interp.open()` 成功后类似的状态变化。完整 LinuxCNC interpreter read/execute、call level、command text、`interp_list` 驱动留给 T-040。
|
||
|
||
### 理由
|
||
|
||
上游 `emctask.cc` 的 plan wait/open/close/reset 是 `emcTaskPlan()` 与 interpreter 之间的关键边界。当前 WASM runtime 已有 staged FS 和简单 program state,但这些状态此前直接由 wrapper 修改。T-039 先把 wait flag、taskplanopen、synch/open/close/reset 决策迁到 source-anchored subset,可以在不提升 full native interpreter readiness 的前提下收敛 wrapper 自有 plan 语义。
|
||
|
||
### 影响
|
||
|
||
- T-039 可闭合。
|
||
- status JSON 的 `emctaskSourceReuse` 新增 `planIssueCount`、`planWaitSetCount`、`planWaitClearCount`、`planSynchCount`、`planOpenCount`、`planCloseCount`、`planResetCount`、`planWaitFlag`、`planOpenFlag`、`planAnchors`。
|
||
- `verify_task_hal_wasm.sh` 新增 plan open/wait/synch evidence 断言。
|
||
- 新增 `tools/verify_task_emctask_plan_open_wait.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-030:T-038 determine/update 输入改由 motion/io snapshot 提供
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-038 将 `wasm_emcTaskUpdate()` 传给 `lc_emctask_subset_update()` 的输入从 task wrapper 自有的 `state/mode` 字符串推导,改为优先来自 task cycle 已读取的 runtime snapshot:
|
||
|
||
- `determineMode()` 的 traj mode 输入来自 `LcmotStatusSnapshot.coord_mode` 和 `teleop_mode`。
|
||
- `determineState()` 的 traj enabled 输入来自 `LcmotStatusSnapshot.motion_enabled`。
|
||
- IO estop 输入来自 task state 的 ESTOP latch 与 IO error latch 聚合。
|
||
- motion id 继续来自 `LcmotStatusSnapshot.motion_id`。
|
||
|
||
当 motion snapshot 尚未有效时,保留 `taskStateFallback,ioSnapshot` 的降级路径;正常 task cycle 证据应记录为 `motionSnapshot,ioSnapshot`。本阶段只收敛 update 输入来源和证据字段,不提升 full native task/status container readiness。
|
||
|
||
### 理由
|
||
|
||
上游 `emctask.cc` 的 `determineMode()`、`determineState()` 和 `emcTaskUpdate()` 读取的是 motion/io 侧状态,而不是由 task wrapper 自行按字符串猜测。T-038 使用当前 task cycle 内的 `LcmotStatusSnapshot` 固定这个边界,可以让 update 语义更接近上游,同时保持 T-022/T-023 已建立的 command buffer、cycle 阶段和 status write 语义。
|
||
|
||
### 影响
|
||
|
||
- T-038 可闭合。
|
||
- status JSON 的 `emctaskSourceReuse` 新增 `snapshotUpdateCount` 和 `updateInputSource`。
|
||
- `verify_task_hal_wasm.sh` 新增 snapshot-fed update 断言。
|
||
- 新增 `tools/verify_task_emctask_update_snapshot.sh` 固定 `determineMode()`、`determineState()`、`emcTaskUpdate()` 的 motion/io snapshot 输入边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-029:T-037 abort/state/mode 采用 `emctask.cc` 窄 command-result 子集
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-037 将 `emcTaskAbort()`、`emcTaskSetMode()`、`emcTaskSetState()` 纳入 `emctask_wasm_subset`,并通过 `LcEmcTaskSubsetCommandResult` 返回 task wrapper 要执行的清理/下发决策:
|
||
|
||
- 清理 interpreter / exec / pause / stepping 状态。
|
||
- state ON 时触发 traj enable。
|
||
- state OFF/ESTOP 时触发 traj disable、motion abort、home reset 和 volatile unhome。
|
||
- explicit abort 时触发 motion abort。
|
||
- mode MANUAL/AUTO/MDI 时由 subset 返回目标 mode 和 traj mode,同步清理 task 执行态。
|
||
|
||
为了保持当前 standalone `lcmot` 的语义稳定,`emcTaskSetMode(AUTO/MDI)` 的窄子集只执行 task/interpreter 清理和 plan synch 标记,不向 `lcmot` 下发 motion abort。完整上游 `emcTaskAbort()` 包含 motion abort,但当前 `lcmot` 的 abort 是终止状态;若 set-mode 直接下发 motion abort,会破坏已有 run smoke。该差异保留为 runtime-edge 降级,后续 native motion abort/reset 语义完善后再收紧。
|
||
|
||
### 理由
|
||
|
||
T-037 的目标是把 abort/state/mode 的决策来源迁入 source-anchored `emctask.cc` 子集,同时不改变 T-022/T-023 已建立的 command buffer 和 task cycle 触发语义。使用 command-result 可以让 wrapper 继续拥有 standalone runtime 状态容器,但不再在分支里直接手写每个上游函数族的决策。
|
||
|
||
### 影响
|
||
|
||
- T-037 可闭合。
|
||
- status JSON 的 `emctaskSourceReuse` 新增 `stateModeIssueCount`、`abortIssueCount`、`stateModeAnchors`。
|
||
- `verify_task_hal_wasm.sh` 继续覆盖 `emctaskSourceReuse`,state matrix 继续证明 send command 不直接改变状态。
|
||
- 新增 `tools/verify_task_emctask_state_mode.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-028:T-036 jog/home/switchkins 通过结构化 `lcmot_write_*` 下发
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-036 将 `taskintf.cc` 的 jog/home/switchkins 子集继续从 task wrapper JSON 兼容路径收拢到结构化 ABI:
|
||
|
||
- `emcJogIncr()` -> `lcmot_write_jog_incr()`
|
||
- `emcJointHome()` -> `lcmot_write_joint_home()`
|
||
- `emcJointUnhome()` -> `lcmot_write_joint_unhome()`
|
||
- `emcMotionSetAout()` -> `lcmot_write_aout()`
|
||
|
||
`taskintf_wasm_subset` 新增 `lc_taskintf_subset_jog_incr_ex()` 和 `lc_taskintf_subset_joint_unhome()`,保留 jog 的 axis/joint mode、distance、velocity、motion id,以及 home/unhome/switchkins 的 command envelope。非本批次的完整 home 状态机、joint active/deactive、limit override、absolute/continuous jog 仍留待后续任务。
|
||
|
||
### 理由
|
||
|
||
上游 `taskintf.cc` 对这些函数同样是填充 `emcmotCommand` 并通过 `usrmotWriteEmcmotCommand()` 发送给 motion。T-035 已把 linear move 的主路径改为结构化 ABI;T-036 继续把 Home/Jog/M428-M430 的现有 smoke 从 JSON 拼接下发迁到结构化 bridge,减少 task wrapper 自有 motion command 语义。
|
||
|
||
### 影响
|
||
|
||
- T-036 可闭合。
|
||
- `lcmot` 新增 `lcmot_write_jog_incr()`、`lcmot_write_joint_home()`、`lcmot_write_joint_unhome()`、`lcmot_write_aout()`。
|
||
- status JSON 的 `taskintfSourceReuse` 新增 `jogHomeSwitchkinsIssueCount`、`jogHomeSwitchkinsStructuredIssueCount` 和 `jogHomeSwitchkinsAnchors`。
|
||
- `verify_task_hal_wasm.sh` 新增 `taskintf_jog_home_switchkins_status=ok`。
|
||
- 新增 `tools/verify_task_taskintf_jog_home_switchkins.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-027:T-035 linear move 通过结构化 `lcmot_write_linear_move()` 下发
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-035 不再让 task wrapper 为 `emcTrajLinearMove()` 主路径拼接 motion JSON。`taskintf_wasm_subset` 新增 `lc_taskintf_subset_linear_move_ex()`,保留 line、motion type、motion id、vel、ini maxvel、acceleration、ini maxjerk 和目标 pose;task runtime 对 linear move 调用结构化 `lcmot_write_linear_move()`,pending execute 队列也携带 `LcTaskIntfSubsetMotionCommand`,flush 时继续走结构化 ABI。
|
||
|
||
非 linear 的 jog/home/switchkins/traj control 暂时保留现有 JSON 兼容路径,留给 T-036 继续收拢。
|
||
|
||
### 理由
|
||
|
||
上游 `emcTrajLinearMove()` 直接填充 `emcmotCommand`,设置 `EMCMOT_SET_LINE`、目标 pose、motion id、tag、motion type、速度/加速度/jerk 等字段,然后通过 `usrmotWriteEmcmotCommand()` 写给 motion。T-035 的结构化 ABI 比 task wrapper JSON 拼接更接近这个边界,也能让 G0/G1 smoke 同时覆盖 `STRAIGHT_TRAVERSE` 和 `STRAIGHT_FEED`。
|
||
|
||
### 影响
|
||
|
||
- T-035 可闭合。
|
||
- `lcmot` 新增 `lcmot_write_linear_move()`。
|
||
- status JSON 的 `taskintfSourceReuse` 新增 `linearMoveIssueCount`、`linearMoveStructuredIssueCount` 和 `linearMoveAnchors`。
|
||
- `verify_task_hal_wasm.sh` 新增 `taskintf_linear_move_status=ok`。
|
||
- 新增 `tools/verify_task_taskintf_linear_move.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-026:T-034 traj control 先接入 `lcmot` 状态和 command envelope
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-034 将 `taskintf.cc` 的 traj control 子集纳入 `taskintf_wasm_subset`:
|
||
|
||
- `emcTrajSetMotionId()`
|
||
- `emcTrajEnable()`
|
||
- `emcTrajDisable()`
|
||
- `emcTrajAbort()`
|
||
- `emcTrajPause()`
|
||
- `emcTrajStep()`
|
||
- `emcTrajResume()`
|
||
|
||
`lcmot` 增加 `motion_enabled` 和 `next_motion_id` 状态。SetMotionId 影响后续 linear/jog motion id;Enable/Disable 更新 motion enabled 状态。为了不破坏既有 low-level motion smoke,当前 runtime 仍允许初始化后直接发送 low-level motion command。
|
||
|
||
### 理由
|
||
|
||
上游 `taskintf.cc` 通过 `usrmotWriteEmcmotCommand()` 将这些 traj control 命令发送给 motion。T-033 已建立 motion init/update/abort bridge,T-034 继续把 pause/step/resume/abort 以及 enable/disable/set-motion-id 收拢到同一个 source-anchored traj control 子集,减少 task wrapper 自行拼接 motion control 语义。
|
||
|
||
### 影响
|
||
|
||
- T-034 可闭合。
|
||
- status JSON 的 `taskintfSourceReuse` 新增 `trajControlIssueCount` 和 `trajControlAnchors`。
|
||
- motion status 新增 `enabled` 和 `nextMotionId`。
|
||
- `verify_task_hal_wasm.sh` 新增 `taskintf_traj_control_status=ok`。
|
||
- 新增 `tools/verify_task_taskintf_traj_control.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-025:T-033 先实现 `taskintf.cc` motion bridge 的窄 init/update/abort 子集
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-033 不直接编译完整 `taskintf.cc` 或 `usrmotintf.cc`,而是在 `taskintf_wasm_subset` 中新增 motion bridge 子集:
|
||
|
||
- `lc_taskintf_subset_motion_init()`
|
||
- `lc_taskintf_subset_motion_update()`
|
||
- `lc_taskintf_subset_motion_abort()`
|
||
|
||
底层 `lcmot` 同步新增:
|
||
|
||
- `LcmotConfigSnapshot`
|
||
- `lcmot_read_config_snapshot()`
|
||
- `lcmot_read_error_message()`
|
||
|
||
task runtime 的 `lctask_init_session()`、周期 motion update 和 task abort path 必须通过这个 bridge。
|
||
|
||
### 理由
|
||
|
||
上游 `emcMotionInit()`、`emcMotionUpdate()`、`emcMotionAbort()` 是 task 到 motion 的关键边界,但完整上游实现仍依赖 native usrmot shared memory、RTAPI、NML 和完整 motion config/error ring。当前阶段先实现窄 bridge,可以让 task 周期更接近 `taskintf.cc` 结构,同时不把未完成 native topology 提前标为 ready。
|
||
|
||
### 影响
|
||
|
||
- T-033 可闭合。
|
||
- status JSON 新增 `taskintfMotionBridge` 验证面。
|
||
- `verify_task_hal_wasm.sh` 新增 `taskintf_motion_bridge_status=ok`。
|
||
- 新增 `tools/verify_task_taskintf_motion_bridge.sh` 固定该边界。
|
||
- readiness 仍保持 `nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
## D-024:`taskintf.cc` usrmot shim 采用窄 `lcmot_*` bridge,不直接编译完整 `usrmotintf.cc`
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-032 采用窄 usrmot shim:
|
||
|
||
```text
|
||
taskintf.cc-compatible calls
|
||
-> wasm usrmot shim
|
||
-> lcmot_* C ABI
|
||
-> standalone motion runtime
|
||
```
|
||
|
||
command write 映射到 `lcmot_write_command_json()`,status read 映射到 `lcmot_read_status_snapshot()`。config read 和 error read 不假装已实现,分别要求后续新增 `lcmot_read_config_snapshot()` 和 `lcmot_read_error_message()` 或等价 ABI。
|
||
|
||
### 理由
|
||
|
||
完整上游 `usrmotintf.cc` 依赖 native shared memory、mutex、command ack 轮询、split read、RTAPI init/exit、motion error ring 和 compensation file loading。WASM 当前是同进程 standalone motion runtime,没有 native emcmot process 和 shared memory ack 通道。
|
||
|
||
窄 shim 可以让 T-033 先实现 `emcMotionInit()`、`emcMotionUpdate()`、`emcMotionAbort()` 的必要路径,同时保持 readiness 口径保守。
|
||
|
||
### 影响
|
||
|
||
- T-032 可闭合。
|
||
- 新增 `working/10-taskintf-usrmot-shim设计.md`。
|
||
- 新增 `tools/verify_task_usrmot_shim_design.sh`。
|
||
- 后续 T-033 实现时必须先补齐或显式处理 config/error read 缺口。
|
||
- 不得把该设计解释为 `nativeTaskReady=true` 或 `nativeHalSyncReady=true`。
|
||
|
||
## D-023:source reuse / drift 文档必须固定 task-HAL 未提升口径
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-030 后,`docs/source-reuse-map.md`、`docs/drift-report.md`、`docs/compatibility-validation.md` 必须同步记录当前 task/motion/HAL runtime 阶段:
|
||
|
||
- task-cycle motion snapshot、command buffer、plan/execute/motion-update/subordinate-sync/status-write 阶段已存在。
|
||
- motion ERROR、soft-limit、top/task/motion/io RCS DONE/EXEC/ERROR 聚合已验证。
|
||
- `emctask.cc`、`taskintf.cc`、`emccanon.cc` 只有窄 source-anchored subsets。
|
||
- 完整 `emc_nml.hh` 只评估,不 vendored、不直接 include。
|
||
- readiness 仍为 `task_hal_runtime_promoted=0`、`nativeTaskReady=false`、`nativeHalSyncReady=false`、`fullLinuxCncProgramExecutionReady=false`。
|
||
|
||
### 理由
|
||
|
||
T-027/T-028/T-029 已经增加了明显更接近 LinuxCNC task 主循环的行为。如果 source reuse 和 drift 文档不及时更新,后续容易把 Web simulation adapter 误读为 full native task/HAL promotion,或把 `emc_nml.hh` 误读为已经可直接 include。
|
||
|
||
### 影响
|
||
|
||
- T-030 可闭合。
|
||
- 新增 `tools/verify_task_source_reuse_drift_docs.sh` 作为文档一致性 gate。
|
||
- 后续 T-032+ 继续推进 usrmot/NML shim 时,必须同步更新这些文档和验证脚本。
|
||
|
||
## D-022:`emc_nml.hh` 暂不直接 include,先走分阶段 typedef / 窄 status 容器
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-029 不直接 include 完整上游 `emc_nml.hh`。当前阶段先采用分阶段 typedef / 窄 `StandaloneEmcStatus` 路线。
|
||
|
||
### 理由
|
||
|
||
`emc_nml.hh` 当前未 vendored 到 `wasm-port/vendor/linuxcnc/src/emc/nml_intf/`。完整上游头文件会拉入 `libnml`、CMS、command/status message 基类、RS274 modal state、canon/tool table 和 active G/M/settings arrays。直接 include 会把 NML transport、CMS serialization、RS274/canon 状态和完整 IO/tool/spindle object graph 提前混入 task main loop 迁移。
|
||
|
||
当前阶段刚闭合 T-028 的 DONE/EXEC/ERROR 聚合,还未完成 T-007 的集中 `EMC_STAT` 等价容器,也未完成 T-032+ 的 usrmot/NML shim。直接 include 风险高于收益。
|
||
|
||
### 影响
|
||
|
||
- T-029 可闭合。
|
||
- 新增 `working/09-emc_nml复用评估.md` 作为复用路线记录。
|
||
- 新增 `tools/verify_task_emc_nml_reuse_plan.sh` 固定该决策。
|
||
- 后续 T-007 建立 `StandaloneEmcStatus` 时,字段命名必须继续对齐 `EMC_STAT` 家族。
|
||
- 后续 T-032+ 补齐 usrmot/NML shim 后,再评估是否 vendor 完整 `emc_nml.hh` 或抽取 status subset header。
|
||
|
||
## D-021:top-level RCS_STATUS 聚合先采用明确 DONE/EXEC/ERROR 字符串
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-028 先在 standalone task runtime 中维护字符串形式的 RCS 聚合状态:
|
||
|
||
- `top_level_rcs_status`
|
||
- `task_rcs_status`
|
||
- `motion_rcs_status`
|
||
- `io_rcs_status`
|
||
|
||
status JSON 导出 `taskTopLevelStatus`、`rcsStatus.top/task/motion/io` 和 `task.status`。聚合顺序按上游 `emctaskmain.cc` 顶层 status write 口径:ERROR 优先,其次 DONE,最后 EXEC。
|
||
|
||
### 理由
|
||
|
||
当前阶段尚未直接复用 `emc_nml.hh` 的完整 `EMC_STAT` 类型,T-029 会单独评估直接 include 或窄 shim。为了先闭合 T-028 的行为验收,用字符串形式记录 DONE/EXEC/ERROR 可以避免提前拉入未评估的 NML 依赖,同时让 JSON surface 明确反映 task/motion/io 三方状态。
|
||
|
||
### 影响
|
||
|
||
- T-028 可闭合。
|
||
- `write_status_snapshot()` 每次写 status buffer 前刷新 top-level 聚合。
|
||
- 现有 `taskTopLevelStatus` 继续保留,但现在来自显式 `top_level_rcs_status`。
|
||
- 后续 T-029/T-030 可以再决定是否把这些字符串替换或映射为 vendored `RCS_STATUS` enum。
|
||
|
||
## D-020:motion ERROR 和 soft-limit 先以测试注入命令覆盖 subordinate sync
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-027 先在 standalone motion runtime 中加入两个测试注入命令:
|
||
|
||
- `EMCMOT_INJECT_ERROR`
|
||
- `EMCMOT_INJECT_SOFT_LIMIT`
|
||
|
||
它们只用于验证 task 周期内 subordinate sync 对 motion ERROR 和 soft-limit snapshot 字段的处理,不代表完整 LinuxCNC motion controller 错误模型已迁移完成。
|
||
|
||
### 理由
|
||
|
||
当前 motion runtime 仍是 deterministic Web simulation adapter。要对齐 `emctaskmain.cc` 的 subordinate sync 行为,需要先有可重复、低成本的 motion error/soft-limit 输入,而不是等待完整 native motion controller 或硬件 limit switch 边界完成。
|
||
|
||
### 影响
|
||
|
||
- T-027 可闭合。
|
||
- `LcmotStatusSnapshot` 尾部追加 `motion_error` 和 `on_soft_limit`,保留已有 C ABI struct 字段 offset。
|
||
- task status JSON 新增 `motion.status`、`motion.motionError`、`motion.onSoftLimit`。
|
||
- task status JSON 新增最小 `taskTopLevelStatus`,用于 T-027 覆盖 ERROR/DONE/EXEC 表面;完整 `RCS_STATUS` 聚合仍由 T-028 推进。
|
||
- `sync_subordinate_states()` 能把 soft-limit 映射为 `MOTION_SOFT_LIMIT`,把 motion ERROR 映射为 `MOTION_ERROR`。
|
||
- 后续 T-028 可以基于这些字段继续做 top-level `RCS_STATUS` 聚合。
|
||
|
||
## D-019:readiness 字段保持 false,直到 full native task/HAL promotion 真实闭合
|
||
|
||
日期:2026-07-08
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
当前 task/motion/HAL simulation runtime 继续标记为 runtime-edge adapter,不标记为 full native task/HAL promotion。
|
||
|
||
当前 readiness contract 固定为:
|
||
|
||
- `task_hal_runtime_promoted=0`
|
||
- `nativeTaskReady=false`
|
||
- `nativeHalSyncReady=false`
|
||
- `fullLinuxCncProgramExecutionReady=false`
|
||
|
||
`docs/source-reuse-map.md` 必须使用上述口径,不得声称 full boundary gates 已将 `nativeTaskReady` 或 `nativeHalSyncReady` 置为 true。
|
||
|
||
### 理由
|
||
|
||
当前 WASM runtime 已有 phase 0 source/probe gates、phase 2 HAL registry、phase 3 motion/HAL servo-cycle C ABI、phase 4 task shim、SDK wrapper,以及 `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的窄 source-anchored subsets。但完整 `emctaskmain.cc` 主循环、NML/native process topology、native HAL sync、full LinuxCNC program execution、硬件 IO、external user-M process 和完整 tool DB process 仍未迁移完成。
|
||
|
||
如果此阶段把 readiness 置 true,会误导后续验收和发布口径。
|
||
|
||
### 影响
|
||
|
||
- T-015 可闭合。
|
||
- 新增 `tools/verify_task_hal_readiness_contract.sh` 作为 readiness 文档/实现一致性 gate。
|
||
- `verify_task_hal_wasm.mjs` 明确断言 `fullLinuxCncProgramExecutionReady=false`。
|
||
- 后续只有在 full native task cycle、native HAL sync、完整 program execution 分别完成并有独立验收证据时,才能改变对应 readiness 字段。
|
||
|
||
## D-018:先引入 `emccanon.cc` canonical linear motion 子集
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-014 先引入 `emccanon.cc` 的 canonical linear motion 子集,而不是直接编译完整 `emccanon.cc`。
|
||
|
||
新增 vendored 文件:
|
||
|
||
- `runtime/core/linuxcnc_task_subset/emccanon_wasm_subset.hh`
|
||
- `runtime/core/linuxcnc_task_subset/emccanon_wasm_subset.cc`
|
||
|
||
该子集锚定上游 `src/emc/task/emccanon.cc`:
|
||
|
||
- `generate_fast_move()`
|
||
- `generate_move()`
|
||
- `STRAIGHT_TRAVERSE()`
|
||
- `STRAIGHT_FEED()`
|
||
|
||
task-HAL WASM build 编译该子集,task runtime 调用它生成 canonical linear move envelope,然后交给 `taskintf_wasm_subset` 生成 task-to-motion command envelope。
|
||
|
||
### 理由
|
||
|
||
完整 `emccanon.cc` 直接依赖 canon 全局状态、offset/unit conversion、`interp_list`、state tags、NURBS、spindle/tool/coolant 等大量 canonical callback 边界。当前阶段先迁入 linear motion envelope,可以让 motion command 生成路径形成 `emccanon -> taskintf -> lcmot` 的分层,而不把未完成的 interpreter/canon 全量状态边界混入 T-014。
|
||
|
||
### 影响
|
||
|
||
- T-014 可闭合。
|
||
- `emccanonSourceReuse` status 字段记录 source path、anchors 和 issue count。
|
||
- `nativeTaskReady`、`nativeHalSyncReady`、`fullLinuxCncProgramExecutionReady` 仍保持 false。
|
||
- 后续 T-041/T-042/T-043/T-044/T-045 可以继续把 canon init、straight motion、dwell/path-control、spindle/tool、motion output/switchkins 子集迁入。
|
||
- `tools/verify_task_emccanon_subset.sh` 成为该子集的 source reuse gate。
|
||
|
||
## D-017:先引入 `taskintf.cc` motion command envelope 子集
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-013 先引入 `taskintf.cc` 的 motion command issuing 子集,而不是直接编译完整 `taskintf.cc`。
|
||
|
||
新增 vendored 文件:
|
||
|
||
- `runtime/core/linuxcnc_task_subset/taskintf_wasm_subset.hh`
|
||
- `runtime/core/linuxcnc_task_subset/taskintf_wasm_subset.cc`
|
||
|
||
该子集锚定上游 `src/emc/task/taskintf.cc`:
|
||
|
||
- `emcTrajAbort()`
|
||
- `emcTrajPause()`
|
||
- `emcTrajStep()`
|
||
- `emcTrajResume()`
|
||
- `emcTrajLinearMove()`
|
||
- `emcJogIncr()`
|
||
- `emcJointHome()`
|
||
- `emcMotionSetAout()`
|
||
|
||
task-HAL WASM build 编译该子集,task runtime 调用它生成 `LcTaskIntfSubsetMotionCommand`,再由 standalone bridge 序列化给现有 `lcmot_*` runtime edge。
|
||
|
||
### 理由
|
||
|
||
完整 `taskintf.cc` 直接依赖 `usrmot`、NML、INI config 和 native motion process。当前阶段的目标是把 task-to-motion issuing 语义先向 LinuxCNC 源码锚点靠拢,而不是一次性恢复 native motion process topology。
|
||
|
||
### 影响
|
||
|
||
- T-013 可闭合。
|
||
- `taskintfSourceReuse` status 字段记录 source path、anchors 和 issue count。
|
||
- `nativeTaskReady`、`nativeHalSyncReady`、`fullLinuxCncProgramExecutionReady` 仍保持 false。
|
||
- 后续 T-033/T-034/T-035/T-036 可以继续把 motion init/update、traj control、linear move、jog/home/switchkins 子集替换为更完整的 `taskintf.cc` bridge。
|
||
- `tools/verify_task_taskintf_subset.sh` 成为该子集的 source reuse gate。
|
||
|
||
## D-016:先引入 `emctask.cc` 状态推导可编译子集
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
T-012 先引入 `emctask.cc` 的最小可编译状态推导子集,而不是直接编译完整 `emctask.cc`。
|
||
|
||
新增 vendored 文件:
|
||
|
||
- `runtime/core/linuxcnc_task_subset/emctask_wasm_subset.hh`
|
||
- `runtime/core/linuxcnc_task_subset/emctask_wasm_subset.cc`
|
||
|
||
该子集锚定上游 `src/emc/task/emctask.cc`:
|
||
|
||
- `determineMode()`
|
||
- `determineState()`
|
||
- `emcTaskUpdate()`
|
||
|
||
task-HAL WASM build 编译该子集,`wasm_emcTaskUpdate()` 调用 `lc_emctask_subset_update()`,status JSON 暴露 `emctaskSourceReuse` 证据。
|
||
|
||
### 理由
|
||
|
||
完整 `emctask.cc` 直接依赖 interpreter、NML、dynamic loading、IO 和 native process 边界。当前阶段若强行编译完整文件,会把多个尚未设计的 runtime edge 混入 T-012,风险和任务边界都过大。
|
||
|
||
先引入状态推导子集可以让 task update 阶段开始使用上游 `emctask.cc` 的明确语义锚点,同时保留 readiness false,避免误报完整 native task runtime 已迁移。
|
||
|
||
### 影响
|
||
|
||
- T-012 可闭合。
|
||
- `nativeTaskReady`、`nativeHalSyncReady`、`fullLinuxCncProgramExecutionReady` 仍保持 false。
|
||
- 后续 T-013/T-014/T-037/T-038 可继续把 `taskintf.cc`、`emccanon.cc`、`emctask.cc` 的命令和 update 函数族迁入。
|
||
- `tools/verify_task_emctask_subset.sh` 成为该子集的 source reuse gate。
|
||
|
||
## D-015:host JSON command 只在 C ABI 边界解析为内部 TaskCommand
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`lctask_send_command_json()` 只承担 host boundary 职责:校验 JSON command envelope、解析为内部 `TaskCommand`、入队 command buffer、写 status buffer。task 语义不再通过该函数执行。
|
||
|
||
`wasm_emcTaskPlan()` 从 command buffer 读取 `TaskCommand`,调用内部 `apply_task_command()` 处理 state/mode/run/pause/resume/step/abort/MDI/JOG/HOME/IO shim 语义。
|
||
|
||
### 理由
|
||
|
||
此前 plan 阶段通过设置 processing 标志并递归调用 `lctask_send_command_json()` 来复用语义分支,导致 C ABI host 边界和 task plan 语义混在一起。T-011 要求 JSON 只作为 C ABI host 边界;内部 task 周期应处理结构化 command envelope,后续才能逐步替换为 `emctask.cc`、`taskintf.cc`、`emccanon.cc` 的源码子集。
|
||
|
||
### 影响
|
||
|
||
- T-011 可闭合。
|
||
- 未知 host JSON command 在 send 边界直接返回 `-1`,不进入 pending command queue。
|
||
- run gate/home gate 等语义拒绝保持为 task 状态错误:写 `errorText`,但 `lctask_run_cycles()` 不因此失败。
|
||
- 后续 T-012/T-013/T-014 可把 `apply_task_command()` 内部 command 家族逐步替换为 vendored LinuxCNC 源码 bridge。
|
||
|
||
## D-014:pause/resume/step motion issue 进入 execute 阶段
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`EMC_TASK_PLAN_PAUSE`、`EMC_TASK_PLAN_STEP`、`EMC_TASK_PLAN_RESUME` 在 plan command handler 中只更新 task/interpreter 状态并排入 `pending_execute_motion_commands`,实际 `EMC_TRAJ_PAUSE`、`EMC_TRAJ_STEP`、`EMC_TRAJ_RESUME` 由 `wasm_emcTaskExecute()` 统一发给 motion runtime。
|
||
|
||
### 理由
|
||
|
||
上游 task 主循环中,外部 command 先进入 task 周期,再通过 plan/execute 阶段影响 motion。若 pause/resume/step 在 `lctask_send_command_json()` 时直接 forward motion,会绕过 command buffer 和周期 snapshot,和 T-022/T-023/T-025 建立的边界不一致。
|
||
|
||
### 影响
|
||
|
||
- T-010 可闭合。
|
||
- pause/resume/step 测试需要先断言 send 后 `pendingCommandDepth` 增加、motion snapshot 不变,再断言 run cycle 后 motion 状态变化。
|
||
- 后续 T-034 可把这组 traj control 命令继续替换为 `taskintf.cc` 的 `emcTrajPause/Step/Resume()` bridge。
|
||
|
||
## D-013:native TRT phase0 probe 使用运行目录机器配置 overlay
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`probe_trt_task_hal_runtime.sh` 不直接修改 `../linuxcnc`。脚本在 `build/native/trt-task-hal-runtime/machine` 生成机器配置 overlay:
|
||
|
||
- 优先 symlink 只读上游 `../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/` 的顶层条目。
|
||
- 对上游缺失的顶层条目,从 `wasm-port/vendor/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/` 补 symlink。
|
||
- 输出 `trt_task_hal_vendor_overlay_*` 证据,保留 fallback 来源。
|
||
|
||
### 理由
|
||
|
||
`verify_task_hal_phase0.sh` 失败的直接原因是上游工作树缺失 `xyzac-trt_cmds.hal`,但 `wasm-port/AGENTS.md` 明确 `../linuxcnc` 是只读输入。运行目录 overlay 可以稳定 native probe 的机器配置输入,同时不污染上游树,也能保留 vendor 来源证据。
|
||
|
||
### 影响
|
||
|
||
- T-016 可闭合。
|
||
- phase0 gate 当前通过,输出 `task_hal_phase0_native_probe_gate=ok`。
|
||
- nativeTaskReady/readiness 仍保持保守 false;overlay 只修复 probe 输入完整性,不代表完整 LinuxCNC task/HAL runtime 已迁移完成。
|
||
|
||
## D-012:区分 task 发起 abort cleanup 与外部 motion/io error
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
subordinate sync 阶段区分两类 abort/error:
|
||
|
||
- task 自己发起的 abort 通过 `task_abort_requested` 标记为预期 cleanup,motion aborted 后 task `exec_state` 保持 `DONE`。
|
||
- 外部 motion abort/error 没有 `task_abort_requested` 标记,motion snapshot 显示 aborted 后 task 进入 `ERROR`,`error_text=MOTION_ABORTED`。
|
||
- standalone IO runtime edge 暂用 `EMC_IO_INJECT_ERROR` 作为窄测试 shim,进入周期后由 subordinate sync 置 `ERROR`,`error_text=IO_ERROR`。
|
||
|
||
### 理由
|
||
|
||
LinuxCNC task 主循环需要区分主动 abort 清理和 subordinate 进程错误。如果二者都映射为 `DONE`,motion/io error 不会暴露;如果二者都映射为 `ERROR`,用户主动 abort 会被误报。
|
||
|
||
### 影响
|
||
|
||
- T-009 可闭合。
|
||
- IO shim 只是 standalone 测试边界,不代表真实 LinuxCNC IO 进程已迁移。
|
||
- T-027 仍需补 soft-limit 等更细的 motion error 注入。
|
||
|
||
## D-011:wait-for-motion 和 queueFull 以周期 motion snapshot 为准
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`WAITING_FOR_MOTION` 和 `WAITING_FOR_MOTION_QUEUE` 的切换必须由 task 周期内的 `LcmotStatusSnapshot` 驱动:
|
||
|
||
- execute 阶段看到上一周期 `motion_snapshot.queue_full` 时,不继续向 motion runtime issue 新 motion command。
|
||
- subordinate sync 阶段看到本周期 queueFull 解除后,把 `WAITING_FOR_MOTION_QUEUE` 切回 `WAITING_FOR_MOTION`。
|
||
- subordinate sync 阶段看到 motion queue/active depth 清空且 in-position 后,把 `WAITING_FOR_MOTION` 收敛到 `DONE`。
|
||
|
||
### 理由
|
||
|
||
LinuxCNC 上游 `emcTaskExecute()` 的 wait 状态依赖 motion status,而 motion status 由每周期 `emcMotionUpdate()` 刷新。如果 task 在发送 command 时直接假设 motion 可用,就会绕过 `emctaskmain.cc` 的周期状态机。
|
||
|
||
### 影响
|
||
|
||
- T-008 可闭合。
|
||
- 后续 T-009/T-027 可以在同一个 subordinate sync 阶段接入 motion error、soft-limit 和 abort cleanup。
|
||
- 后续 T-028 可以基于这些 task/motion 状态继续做 top-level `RCS_STATUS` 聚合。
|
||
|
||
## D-010:形成周期阶段骨架,并将 MDI/JOG/HOME issue 放入 execute 阶段
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
本轮把 `lctask_run_cycles()` 拆成 `task_cycle_begin()`、`task_read_commands()`、`wasm_emcTaskPlan()`、`wasm_emcTaskExecute()`、`wasm_emcMotionUpdate()`、`sync_subordinate_states()`、`wasm_emcTaskUpdate()`、`update_top_level_status()`、`write_status_snapshot()` 等阶段函数。
|
||
|
||
当前 command handler 仍作为 Phase 4 adapter 被 `wasm_emcTaskPlan()` 调用,保证 state/mode/home/run gate 由 task cycle 触发。MDI/JOG/HOME 的 motion issue 通过 `pending_execute_motion_commands` 排队,并由 `wasm_emcTaskExecute()` 统一发给 motion runtime。
|
||
|
||
### 理由
|
||
|
||
T-023 的主要风险是让 `lctask_run_cycles()` 继续成为混合大函数,后续无法逐段替换 `emctask.cc`、`taskintf.cc`、`emccanon.cc`。先建立清晰阶段边界,可以让后续把命令族迁入对应 plan/execute 函数时保持测试稳定。
|
||
|
||
### 影响
|
||
|
||
- T-006、T-023、T-024、T-025 可闭合。
|
||
- T-008 是下一优先任务,需要把 wait-for-motion 和 queueFull 语义迁到周期 motion snapshot。
|
||
- `sync_subordinate_states()`、`wasm_emcTaskUpdate()`、`update_top_level_status()` 当前是窄占位,后续 T-027/T-028/T-038 继续扩展。
|
||
|
||
## D-008:先闭合 motion snapshot/status buffer,再推进 command queue
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
本轮先完成 `LcmotStatusSnapshot`、`lcmot_read_status_snapshot()`、`wasm_emcMotionUpdate()` 和 task status buffer。`lctask_read_status_json()` 只导出最后一次 task status write,不再在读取时同步 motion runtime。
|
||
|
||
完成 motion snapshot/status buffer 后,本轮继续推进 `lctask_send_command_json()` 的 command slot/queue 改造,将 T-022 纳入同一批验收。T-023 的周期函数拆分仍单独推进。
|
||
|
||
### 理由
|
||
|
||
motion snapshot/status buffer 是 `emctaskmain.cc` 周期对标的前置基础。如果同时迁移 command queue、plan、execute,会扩大改动面,并让 status 读取边界和 command side effect 边界难以分别验收。
|
||
|
||
本轮先用测试固定:low-level motion runtime 单独变化不会被 task status read 捕获,只有下一次 `lctask_run_cycles()` 才会写入 task status snapshot。随后把 task command send 改为入队,状态变化也必须等待 `lctask_run_cycles()` 消费 command。
|
||
|
||
### 影响
|
||
|
||
- T-002、T-003、T-004、T-005、T-018、T-019、T-020、T-021、T-022、T-026 可闭合。
|
||
- T-023 仍为下一优先任务,必须把 command queue 消费逻辑继续拆成 command read / plan / execute。
|
||
- 后续 T-023 拆周期函数时,应把当前 `wasm_emcMotionUpdate()` 和 `write_status_snapshot()` 保留下来,并补齐 command read、plan、execute、subordinate sync、task update 的阶段函数。
|
||
|
||
## D-009:task command send 入队,语义变化由 task cycle 消费
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`lctask_send_command_json()` 默认只验证 command 类型并写入 `TaskRuntime.pending_commands`。`lctask_run_cycles()` 在每个 task cycle 开始消费 pending command,并在该周期内触发 state/mode/run/pause/resume/MDI/JOG/HOME/abort 等现有语义。
|
||
|
||
### 理由
|
||
|
||
LinuxCNC 上游 task 主循环通过 command buffer 在周期内读取命令,而不是让外部 send API 直接改变 task 状态。先建立 command buffer/slot,可以让后续 T-023 把 command read、plan、execute 拆成明确阶段。
|
||
|
||
### 影响
|
||
|
||
- task status 新增 `pendingCommandDepth`。
|
||
- 发送 command 后,如果不调用 `lctask_run_cycles()`,task `state/mode/interpState/execState` 不应变化。
|
||
- 现有 command 处理逻辑仍集中在一个消费分支中;T-023 需要继续拆成独立周期函数。
|
||
|
||
## D-001:以 LinuxCNC `emctaskmain.cc` 周期结构作为对标主线
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
后续 task/motion/HAL runtime 推进以 LinuxCNC `emctaskmain.cc` 的主循环结构为主线,而不是继续扩展当前 `TaskRuntime` 自有状态机。
|
||
|
||
### 理由
|
||
|
||
上游 task 主循环的关键语义来自固定周期:
|
||
|
||
1. 读取 command。
|
||
2. `emcTaskPlan()`。
|
||
3. `emcTaskExecute()`。
|
||
4. `emcMotionUpdate(&emcStatus->motion)`。
|
||
5. subordinate sync。
|
||
6. `emcTaskUpdate()`。
|
||
7. status write。
|
||
|
||
当前 WASM minimal adapter 已能 smoke,但 motion 状态没有成为 task 周期内的控制输入。若继续扩展自有状态机,会偏离 `wasm-port/AGENTS.md` 中“复用 LinuxCNC 源码、不要新增项目自有 CNC 语义”的原则。
|
||
|
||
### 影响
|
||
|
||
- 新开发优先补 task 周期结构。
|
||
- JSON command/status 只能作为 host boundary,不作为 CNC/task 语义来源。
|
||
- 后续任务需要逐步引入 vendored/upstream task 源码或窄 shim。
|
||
|
||
## D-002:motion snapshot 先结构化读取,不在 task 周期解析 JSON
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
task 周期内读取 motion 状态时,应新增结构化 C/C++ snapshot 边界,不在 `lctask_run_cycles()` 内解析 `lcmot_read_status_json()` 输出。
|
||
|
||
### 理由
|
||
|
||
- LinuxCNC 原生路径是 `emcMotionUpdate(&emcStatus->motion)` 写结构化状态。
|
||
- JSON 是 Web/SDK 输出格式,不应成为内部控制语义。
|
||
- 结构化 snapshot 更容易映射到 `EMC_STAT.motion`。
|
||
|
||
### 影响
|
||
|
||
- `linuxcnc_motion_runtime.c` 需要新增内部 snapshot 读取函数或共享 header。
|
||
- `status_json()` 后续应导出 task 已持有的 snapshot。
|
||
|
||
## D-003:readiness 字段必须保守
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`nativeTaskReady`、`nativeHalSyncReady`、`fullLinuxCncProgramExecutionReady` 只能在对应能力真实完成并有验收证据后置为 true。
|
||
|
||
### 理由
|
||
|
||
当前代码和测试输出仍为 false,而部分文档文字曾出现 true 的表述,容易造成推进误判。readiness 是边界契约,必须保守。
|
||
|
||
### 影响
|
||
|
||
- `docs/source-reuse-map.md` 需要在后续任务中修正。
|
||
- 测试应断言 readiness 与真实能力一致。
|
||
|
||
## D-004:native process/realtime 拓扑不是本阶段目标
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
本阶段只对标 task 主循环语义和状态流,不尝试恢复 LinuxCNC 原生多进程、NML transport、realtime kernel 或真实硬件控制。
|
||
|
||
### 理由
|
||
|
||
`wasm-port` 目标是 standalone WASM simulation。运行时边界可以替换 file IO、IPC、HAL runtime、process model 和 browser integration,但 CNC/task 语义应来自 LinuxCNC。
|
||
|
||
### 影响
|
||
|
||
- process spawning、external user-M、native GUI、真实 realtime driver 继续作为 runtime-edge 或 blocked 项处理。
|
||
- 任何 standalone 差异必须写入决策或设计文档。
|
||
|
||
## D-005:status read 不同步 motion,不产生语义副作用
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`lctask_read_status_json()` 只能导出最后一次 task cycle 写出的 status snapshot,不允许在读取 status 时调用 motion runtime 来刷新 task 语义状态。
|
||
|
||
### 理由
|
||
|
||
LinuxCNC 上游是在 task 主循环中调用 `emcMotionUpdate(&emcStatus->motion)`,随后 `emcStatusBuffer->write(emcStatus)`。GUI/客户端读取 status buffer 不应改变 task/motion 语义。如果 WASM status read 同步 motion,就会掩盖“task 周期没有读取 motion”的缺陷。
|
||
|
||
### 影响
|
||
|
||
- 需要建立 task status buffer 等价物。
|
||
- 需要新增测试证明 status read 不推进、不同步、不改变 task 状态。
|
||
- motion JSON 可以作为 low-level debug API 保留,但不能作为 task status 事实源。
|
||
|
||
## D-006:command send 只入队,语义变化由 task cycle 产生
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
`lctask_send_command_json()` 后续应只解析并入队 command envelope,不直接修改 task `state/mode/interpState/execState`,也不直接 forward motion command。LinuxCNC 语义变化必须发生在 `lctask_run_cycles()` 的 command read、plan、execute 阶段。
|
||
|
||
### 理由
|
||
|
||
上游 `emctaskmain.cc` 每周期通过 `emcCommandBuffer->read()` 获取命令,再运行 `emcTaskPlan()` 和 `emcTaskExecute()`。当前 send API 直接改状态,是 host convenience,不是 LinuxCNC task 主循环语义。
|
||
|
||
### 影响
|
||
|
||
- 现有测试需要调整:send command 后必须 run cycle 才断言状态变化。
|
||
- 当前 immediate MDI/JOG/HOME forward motion 逻辑要迁到 execute 阶段。
|
||
- C ABI 仍可保持简单,但语义边界必须改为 command buffer。
|
||
|
||
## D-007:先迁 `taskintf.cc` minimal bridge,再迁 `emctask.cc` 和 `emccanon.cc`
|
||
|
||
日期:2026-07-07
|
||
|
||
状态:已采纳
|
||
|
||
### 决策
|
||
|
||
上游 task 源码替换顺序采用:
|
||
|
||
1. `taskintf.cc` minimal motion bridge。
|
||
2. `emctask.cc` abort/state/mode/update。
|
||
3. `emctask.cc` plan wrapper。
|
||
4. `emccanon.cc` straight motion 子集。
|
||
5. `emctaskmain.cc` execute 分支接 `interp_list`。
|
||
6. `emccanon.cc` spindle/tool/io 子集。
|
||
|
||
### 理由
|
||
|
||
`emctask.cc` 和 `emccanon.cc` 都依赖 task 到 motion 的接口。若没有先建立 `taskintf.cc` 到 `lcmot` 的 bridge,`emctask.cc` 的 state/mode/abort 和 `emccanon.cc` 的 `EMC_TRAJ_*` command 只能继续落回 JSON 自有逻辑。先迁 `taskintf.cc` minimal bridge,可以让后续上游函数真正通过 LinuxCNC task/motion 接口工作。
|
||
|
||
### 影响
|
||
|
||
- T-032 到 T-036 优先级高于 T-037 之后的源码替换。
|
||
- `emccanon.cc` 迁移不得绕过 `interp_list` 直接输出 JSON。
|
||
- `taskintf.cc` 中无法连接真实硬件/RT 的部分必须显式 shim 到 `lcmot/lchal` runtime。
|