63 KiB
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_REQUIREDJSON-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 同步新增:
LcmotConfigSnapshotlcmot_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:
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_statustask_rcs_statusmotion_rcs_statusio_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_STATUSenum。
D-020:motion ERROR 和 soft-limit 先以测试注入命令覆盖 subordinate sync
日期:2026-07-08
状态:已采纳
决策
T-027 先在 standalone motion runtime 中加入两个测试注入命令:
EMCMOT_INJECT_ERROREMCMOT_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=0nativeTaskReady=falsenativeHalSyncReady=falsefullLinuxCncProgramExecutionReady=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 文件:
vendor/linuxcnc/src/emc/task/emccanon_wasm_subset.hhvendor/linuxcnc/src/emc/task/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 可闭合。
emccanonSourceReusestatus 字段记录 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 文件:
vendor/linuxcnc/src/emc/task/taskintf_wasm_subset.hhvendor/linuxcnc/src/emc/task/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 可闭合。
taskintfSourceReusestatus 字段记录 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.ccbridge。 tools/verify_task_taskintf_subset.sh成为该子集的 source reuse gate。
D-016:先引入 emctask.cc 状态推导可编译子集
日期:2026-07-07
状态:已采纳
决策
T-012 先引入 emctask.cc 的最小可编译状态推导子集,而不是直接编译完整 emctask.cc。
新增 vendored 文件:
vendor/linuxcnc/src/emc/task/emctask_wasm_subset.hhvendor/linuxcnc/src/emc/task/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 后 taskexec_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(),taskstate/mode/interpState/execState不应变化。 - 现有 command 处理逻辑仍集中在一个消费分支中;T-023 需要继续拆成独立周期函数。
D-001:以 LinuxCNC emctaskmain.cc 周期结构作为对标主线
日期:2026-07-07
状态:已采纳
决策
后续 task/motion/HAL runtime 推进以 LinuxCNC emctaskmain.cc 的主循环结构为主线,而不是继续扩展当前 TaskRuntime 自有状态机。
理由
上游 task 主循环的关键语义来自固定周期:
- 读取 command。
emcTaskPlan()。emcTaskExecute()。emcMotionUpdate(&emcStatus->motion)。- subordinate sync。
emcTaskUpdate()。- 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 源码替换顺序采用:
taskintf.ccminimal motion bridge。emctask.ccabort/state/mode/update。emctask.ccplan wrapper。emccanon.ccstraight motion 子集。emctaskmain.ccexecute 分支接interp_list。emccanon.ccspindle/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/lchalruntime。