Files
cnc_wams/wasm-port/working/06-决策记录.md
2026-07-10 03:22:55 -04:00

63 KiB
Raw Blame History

06-决策记录

D-046task status JSON 不再保留旧顶层字段兼容视图

日期2026-07-08

状态:已采纳

决策

lctask_read_status_json() 只通过 emcStatus 导出 task/motion/io/top 状态,不再输出 taskTopLevelStatusrcsStatus、顶层 taskservoCycle、顶层 motionStatus

本决策取代 D-044 中“既有旧字段保留为兼容视图”的部分D-044 中“status JSON 对标 LinuxCNC status buffer、JSON 不能成为事实源、read status 只读”的部分继续有效。

理由

上层项目已经迁移到 emcStatus 契约。继续在源头输出旧字段会扩大状态表面,导致 SDK/UI 继续依赖旧字段,并让后续 LinuxCNC EMC_STAT 对标和契约测试同时维护两套入口。

影响

  • status_json() 移除旧顶层字段输出。
  • emcStatus.taskemcStatus.motion 补齐旧视图中仍需要的字段。
  • WASM、SDK、state matrix 和 status contract 测试均对旧顶层字段做负向断言。
  • 后续新增字段只能进入 emcStatus 或底层 C/C++ status buffer不新增旧字段兼容视图。

D-045SJ-1 到 SJ-5 必须进入任务矩阵并由 contract gate 固定

日期2026-07-08

状态:已采纳

决策

11-WASM核心状态机边界与后续完善路线.md12-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。

理由

上一轮只检查任务矩阵,导致 1112 中已经写明目标和验收标准的任务没有被发现。后续只要文档中出现可执行实现项,就必须同步进入任务矩阵、验收证据和 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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-044status JSON 对标 LinuxCNC status buffer而不是替代状态机

日期2026-07-08

状态:已采纳

决策

后续在 WASM 中解决 status JSON 时,对标 LinuxCNC 的 EMC_STAT / status buffer 模型C/C++ 侧维护 StandaloneEmcStatus 或后续 EMC_STAT 等价容器,write_status_snapshot() 写入最后一次 status bufferlctask_read_status_json() 只把该 buffer 序列化为 JSON。

新增 LinuxCNC 对标字段默认进入 emcStatus JSON 对象。既有 taskmotionStatusrcsStatustaskTopLevelStatus 等字段保留为兼容视图,但必须从同一 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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-042T-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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-041T-048 将 working closure gate 纳入全局文档一致性 gate

日期2026-07-08

状态:已采纳

决策

T-048 将 tools/verify_task_working_closure.sh 记录到 docs/source-reuse-map.mddocs/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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-040T-047 将 working 索引收口为“矩阵闭合、后续先补任务”

日期2026-07-08

状态:已采纳

决策

T-047 不新增 runtime 行为,只收口 working 文档索引和闭合 gate。working/README.md01-项目功能内容.md09-emc_nml复用评估.md 的当前状态描述更新为 T-007/T-046 后的事实:StandaloneEmcStatus 已建立task status 来自周期 snapshot/status writeRUN 主路径不依赖 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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-039T-007 采用 StandaloneEmcStatus 作为当前阶段 EMC_STAT 等价容器

日期2026-07-08

状态:已采纳

决策

T-007 在 linuxcnc_task_hal_wasm.cpp 内建立 StandaloneEmcStatus,包含 StandaloneEmcTaskStatusStandaloneEmcMotionStatusStandaloneEmcIoStatus。该容器集中保存当前 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,并让兼容字段 taskTopLevelStatusrcsStatustaskmotionStatus 读取同一份容器状态。

理由

直接引入完整上游 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=StandaloneEmcStatusemcStatus
  • 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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-038T-046 主 RUN 路径移除 JSON motion plan 依赖,保留 timed-plan 兼容入口

日期2026-07-08

状态:已采纳

决策

T-046 将默认 RUN 文件验证路径切换为 staged program 驱动:emcTaskPlanRead() 读取已打开程序行,emcTaskPlanCommand() 生成 command evidenceemcTaskPlanExecute() 进入 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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-037T-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 返回 LcEmcCanonSubsetOutputCommandwrapper 将这些 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_DOUTEMC_MOTION_SET_AOUTEMC_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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-036T-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 envelopewrapper 将这些 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/M5T...、精确 M6M61 Q...。精确 M-code 解析用于避免 M428/M429/M430 这类 switchkins special-case 被误判为 M4。status JSON 新增 spindleCommandCountspindleAppendCountlastSpindleCommandlastSpindlelastSpindleSpeedlastSpindleWaittoolCommandCounttoolAppendCountlastToolCommandlastToolspindleToolAnchors

理由

上游 spindle/tool canonical callbacks 构造 EMC_SPINDLE_SPEEDEMC_SPINDLE_ONEMC_SPINDLE_OFFEMC_TOOL_PREPAREEMC_TOOL_LOADEMC_TOOL_SET_NUMBEREMC_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.mddocs/drift-report.mddocs/compatibility-validation.mdtools/verify_task_source_reuse_drift_docs.sh 记录 T-044 spindle/tool 映射。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-035T-043 dwell/path-control 采用 emccanon.cc 窄 interp-list evidence

日期2026-07-08

状态:已采纳

决策

T-043 将 DWELL()SET_MOTION_CONTROL_MODE() 纳入 emccanon_wasm_subsetlc_emccanon_subset_dwell() 返回 LcEmcCanonSubsetDelay,用于记录 EMC_TRAJ_DELAY / interp_list evidencelc_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 前识别 G4G61G61.1G64,将 dwell 和 path-control 作为 canon non-motion command 记录到 emccanonSourceReuse,不发 motion command。status JSON 新增 dwellCountdelayAppendCountlastDwellSecondspathControlCounttermCondAppendCountlastPathModelastTermConditionlastPathTolerancedwellPathControlAnchors

理由

上游 DWELL() 生成 EMC_TRAJ_DELAY 并 append 到 interp_listSET_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.mddocs/drift-report.mddocs/compatibility-validation.mdtools/verify_task_source_reuse_drift_docs.sh 记录 T-043 dwell/path-control 映射。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-034T-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() 继续返回 LcEmcCanonSubsetLinearMovewrapper 在 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_MOVEinterp_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 新增 straightTraverseCountstraightFeedCountlinearMoveAppendCountlastLinearMoveLinelastLinearMoveTypelastInterpListCommandstraightMotionAnchors
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-033T-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 扩展为 initCountfinishCountresetCountunitSetCountpositionGetCountendpointUpdateCountlengthUnitsexternalLengthUnitsexternalAngleUnitsendpointinitFinishUnitAnchors。该状态只作为 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.mddocs/drift-report.mddocs/compatibility-validation.mdtools/verify_task_source_reuse_drift_docs.sh 记录 T-041 canon init/finish/unit/endpoint 映射。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-032T-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 programtask cycle 可通过 PlanRead/Command/Execute 读取 staged program lines再映射到现有 emccanon straight motion 和 taskintf structured motion issue 路径。为了避免 T-039 的 wait flag 阻塞 T-040 readRUN 起点不再立即 set-waitwait 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_listT-040 先建立这个窄边界,使 staged program 可直接驱动 motion issuing不再把 JSON motion plan 作为 RUN 的必要条件。

影响

  • T-040 可闭合。
  • status JSON 的 emctaskSourceReuse 新增 planReadCountplanExecuteCountplanLineCountplanLevelCountplanCommandCountinterpListAppendCountplanReadExecuteAnchors 等证据字段。
  • 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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-031T-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 新增 planIssueCountplanWaitSetCountplanWaitClearCountplanSynchCountplanOpenCountplanCloseCountplanResetCountplanWaitFlagplanOpenFlagplanAnchors
  • verify_task_hal_wasm.sh 新增 plan open/wait/synch evidence 断言。
  • 新增 tools/verify_task_emctask_plan_open_wait.sh 固定该边界。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-030T-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_modeteleop_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.ccdetermineMode()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 新增 snapshotUpdateCountupdateInputSource
  • verify_task_hal_wasm.sh 新增 snapshot-fed update 断言。
  • 新增 tools/verify_task_emctask_update_snapshot.sh 固定 determineMode()determineState()emcTaskUpdate() 的 motion/io snapshot 输入边界。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-029T-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 新增 stateModeIssueCountabortIssueCountstateModeAnchors
  • verify_task_hal_wasm.sh 继续覆盖 emctaskSourceReusestate matrix 继续证明 send command 不直接改变状态。
  • 新增 tools/verify_task_emctask_state_mode.sh 固定该边界。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-028T-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 的主路径改为结构化 ABIT-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 新增 jogHomeSwitchkinsIssueCountjogHomeSwitchkinsStructuredIssueCountjogHomeSwitchkinsAnchors
  • verify_task_hal_wasm.sh 新增 taskintf_jog_home_switchkins_status=ok
  • 新增 tools/verify_task_taskintf_jog_home_switchkins.sh 固定该边界。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-027T-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 和目标 posetask runtime 对 linear move 调用结构化 lcmot_write_linear_move()pending execute 队列也携带 LcTaskIntfSubsetMotionCommandflush 时继续走结构化 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_TRAVERSESTRAIGHT_FEED

影响

  • T-035 可闭合。
  • lcmot 新增 lcmot_write_linear_move()
  • status JSON 的 taskintfSourceReuse 新增 linearMoveIssueCountlinearMoveStructuredIssueCountlinearMoveAnchors
  • verify_task_hal_wasm.sh 新增 taskintf_linear_move_status=ok
  • 新增 tools/verify_task_taskintf_linear_move.sh 固定该边界。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-026T-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_enablednext_motion_id 状态。SetMotionId 影响后续 linear/jog motion idEnable/Disable 更新 motion enabled 状态。为了不破坏既有 low-level motion smoke当前 runtime 仍允许初始化后直接发送 low-level motion command。

理由

上游 taskintf.cc 通过 usrmotWriteEmcmotCommand() 将这些 traj control 命令发送给 motion。T-033 已建立 motion init/update/abort bridgeT-034 继续把 pause/step/resume/abort 以及 enable/disable/set-motion-id 收拢到同一个 source-anchored traj control 子集,减少 task wrapper 自行拼接 motion control 语义。

影响

  • T-034 可闭合。
  • status JSON 的 taskintfSourceReuse 新增 trajControlIssueCounttrajControlAnchors
  • motion status 新增 enablednextMotionId
  • verify_task_hal_wasm.sh 新增 taskintf_traj_control_status=ok
  • 新增 tools/verify_task_taskintf_traj_control.sh 固定该边界。
  • readiness 仍保持 nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-025T-033 先实现 taskintf.cc motion bridge 的窄 init/update/abort 子集

日期2026-07-08

状态:已采纳

决策

T-033 不直接编译完整 taskintf.ccusrmotintf.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=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=false

D-024taskintf.cc usrmot shim 采用窄 lcmot_* bridge不直接编译完整 usrmotintf.cc

日期2026-07-08

状态:已采纳

决策

T-032 采用窄 usrmot shim

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=truenativeHalSyncReady=true

D-023source reuse / drift 文档必须固定 task-HAL 未提升口径

日期2026-07-08

状态:已采纳

决策

T-030 后,docs/source-reuse-map.mddocs/drift-report.mddocs/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.cctaskintf.ccemccanon.cc 只有窄 source-anchored subsets。
  • 完整 emc_nml.hh 只评估,不 vendored、不直接 include。
  • readiness 仍为 task_hal_runtime_promoted=0nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=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-022emc_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-021top-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 导出 taskTopLevelStatusrcsStatus.top/task/motion/iotask.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-020motion 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_erroron_soft_limit,保留已有 C ABI struct 字段 offset。
  • task status JSON 新增 motion.statusmotion.motionErrormotion.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-019readiness 字段保持 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 已将 nativeTaskReadynativeHalSyncReady 置为 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.cctaskintf.ccemccanon.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。
  • nativeTaskReadynativeHalSyncReadyfullLinuxCncProgramExecutionReady 仍保持 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。
  • nativeTaskReadynativeHalSyncReadyfullLinuxCncProgramExecutionReady 仍保持 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 可闭合。
  • nativeTaskReadynativeHalSyncReadyfullLinuxCncProgramExecutionReady 仍保持 false。
  • 后续 T-013/T-014/T-037/T-038 可继续把 taskintf.ccemccanon.ccemctask.cc 的命令和 update 函数族迁入。
  • tools/verify_task_emctask_subset.sh 成为该子集的 source reuse gate。

D-015host 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.cctaskintf.ccemccanon.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-014pause/resume/step motion issue 进入 execute 阶段

日期2026-07-07

状态:已采纳

决策

EMC_TASK_PLAN_PAUSEEMC_TASK_PLAN_STEPEMC_TASK_PLAN_RESUME 在 plan command handler 中只更新 task/interpreter 状态并排入 pending_execute_motion_commands,实际 EMC_TRAJ_PAUSEEMC_TRAJ_STEPEMC_TRAJ_RESUMEwasm_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.ccemcTrajPause/Step/Resume() bridge。

D-013native 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 仍保持保守 falseoverlay 只修复 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 标记为预期 cleanupmotion aborted 后 task exec_state 保持 DONE
  • 外部 motion abort/error 没有 task_abort_requested 标记motion snapshot 显示 aborted 后 task 进入 ERRORerror_text=MOTION_ABORTED
  • standalone IO runtime edge 暂用 EMC_IO_INJECT_ERROR 作为窄测试 shim进入周期后由 subordinate sync 置 ERRORerror_text=IO_ERROR

理由

LinuxCNC task 主循环需要区分主动 abort 清理和 subordinate 进程错误。如果二者都映射为 DONEmotion/io error 不会暴露;如果二者都映射为 ERROR,用户主动 abort 会被误报。

影响

  • T-009 可闭合。
  • IO shim 只是 standalone 测试边界,不代表真实 LinuxCNC IO 进程已迁移。
  • T-027 仍需补 soft-limit 等更细的 motion error 注入。

D-011wait-for-motion 和 queueFull 以周期 motion snapshot 为准

日期2026-07-07

状态:已采纳

决策

WAITING_FOR_MOTIONWAITING_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.cctaskintf.ccemccanon.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

状态:已采纳

决策

本轮先完成 LcmotStatusSnapshotlcmot_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-009task command send 入队,语义变化由 task cycle 消费

日期2026-07-07

状态:已采纳

决策

lctask_send_command_json() 默认只验证 command 类型并写入 TaskRuntime.pending_commandslctask_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-002motion 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-003readiness 字段必须保守

日期2026-07-07

状态:已采纳

决策

nativeTaskReadynativeHalSyncReadyfullLinuxCncProgramExecutionReady 只能在对应能力真实完成并有验收证据后置为 true。

理由

当前代码和测试输出仍为 false而部分文档文字曾出现 true 的表述容易造成推进误判。readiness 是边界契约,必须保守。

影响

  • docs/source-reuse-map.md 需要在后续任务中修正。
  • 测试应断言 readiness 与真实能力一致。

D-004native 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-005status 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-006command 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.ccemccanon.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.ccemccanon.cc 都依赖 task 到 motion 的接口。若没有先建立 taskintf.cclcmot 的 bridgeemctask.cc 的 state/mode/abort 和 emccanon.ccEMC_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。