# 10 RUN 控制类测试与 INI 周期派生详细步骤

生成时间：2026-06-22

## 1. 本轮目标

在 `05` 到 `09` 已完成 RUN 主链路、浏览器 RUN 证据和米单位场景的基础上，继续补齐 `07`、`09` 中列出的剩余可自动验证项。

本轮执行范围：

```text
1. ABORT 后 taskHalStatusLoop.active=false，runState/status 正确。
2. STEP 在 task/HAL runtime loaded 时仍消费 linuxcnc-task-motion-hal-wasm feedback。
3. RUN gate 对 machine ON / AUTO / homed / opened-file 保持细粒度失败断言。
4. taskHalStatusLoop 的 taskPeriodNs/servoPeriodNs 从 INI TASK.CYCLE_TIME / EMCMOT.SERVO_PERIOD 派生。
5. xyzbc-trt 增加 RUN status loop 对称 node 测试。
```

不在本轮执行：

```text
1. 新增浏览器 desktop/mobile 米尺度截图证据。
2. G20/G21 中途切换浏览器端预览用例。
3. 新增真实 LinuxCNC native 对照资产。
```

## 2. 执行顺序

### 步骤 1：建立当前基线

运行：

```bash
node web-rtcp-5axis-sim-plan/tests/node/verify_run_feedback_loop.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_run_preconditions.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_linuxcnc_task_hal_runtime.mjs
```

通过标准：

```text
现有 xyzac RUN feedback loop、RUN preconditions、task/HAL runtime smoke 均可复现。
```

### 步骤 2：实现 INI 周期派生

代码落点：

```text
app/src/state/store.js
```

实现要求：

```text
1. 从 state.linuxCncIniConfig.task.cycleTimeSeconds 派生 taskPeriodNs。
2. 从 state.linuxCncIniConfig.emcmot.servoPeriodNs 派生 servoPeriodNs。
3. runTaskHalCommandSequence 默认使用派生周期。
4. startTaskHalStatusLoop 默认使用派生周期。
5. 如果 INI 字段缺失，才回退到原默认值 task=10000000ns / servo=1000000ns。
```

验收断言：

```text
xyzac-trt.ini: TASK.CYCLE_TIME=0.010 -> taskPeriodNs=10000000。
xyzac-trt.ini: EMCMOT.SERVO_PERIOD=1000000 -> servoPeriodNs=1000000。
```

### 步骤 3：补 ABORT/STEP node 测试

测试落点：

```text
tests/node/verify_run_feedback_loop.mjs
```

新增断言：

```text
1. RUN 后 loop sequence/tick/history 由 task/HAL feedback 产生。
2. ABORT 后 taskHalStatusLoop.active=false。
3. ABORT 后 stopReason 为 aborted 或 runState 被 task/HAL status 收敛到 stopped/complete。
4. STEP 后 programRuntimeFeedback.sourceMode 是 linuxcnc-task-motion-hal-wasm。
5. STEP 后不出现 fixture-line-playback。
```

### 步骤 4：补 RUN gate 细粒度断言

测试落点：

```text
tests/node/verify_run_preconditions.mjs
```

新增断言：

```text
1. INI/profile/kinematics/machine-file ready 但 machine off 时，RUN gate 返回 machine must be on。
2. machine on 但未 home 时，RUN gate 返回 home machine first。
3. homed 但 manual mode 时，RUN gate 返回 switch to auto mode first。
4. selected G-code/session 缺失时，validateRunPreconditions 返回 no machine-file G-code opened。
```

### 步骤 5：补 xyzbc RUN status loop 对称测试

测试落点：

```text
tests/node/verify_run_feedback_loop.mjs
```

流程：

```text
1. 加载 profile=xyzbc-trt。
2. 解析 xyzbc-trt.ini。
3. attach xyzbc-trt kinematics runtime。
4. stage machine files。
5. 选择 xyzbc_switchkins.ngc 或 boat-xyzbc.ngc。
6. POWER -> HOME -> AUTO -> RUN。
7. 断言 taskHalStatusLoop/profile/kinematics/sourceMode/history 与 xyzbc 一致。
```

### 步骤 6：验证

运行：

```bash
node web-rtcp-5axis-sim-plan/tests/node/verify_run_preconditions.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_run_feedback_loop.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_linuxcnc_task_hal_runtime.mjs
npm --prefix web-rtcp-5axis-sim-plan/app run build
npm --prefix web-rtcp-5axis-sim-plan/app run smoke:node
```

通过标准：

```text
所有命令返回 0。
新增断言覆盖 ABORT、STEP、RUN gate、INI cycle period、xyzbc RUN symmetry。
```

## 3. 完成记录模板

执行完成后，追加记录：

```text
1. 修改文件。
2. 新增断言。
3. 验证命令与结果。
4. 未完成项和下一步。
```

## 4. 本轮完成记录

完成时间：2026-06-22 17:45 EDT

修改文件：

```text
app/src/state/store.js
tests/node/verify_run_feedback_loop.mjs
tests/node/verify_run_preconditions.mjs
working_run/README.md
working_run/10-run-control-tests-and-ini-cycle-steps.md
```

完成内容：

```text
1. runTaskHalCommandSequence 默认周期改为从 INI 派生：
   TASK.CYCLE_TIME -> taskPeriodNs。
   EMCMOT.SERVO_PERIOD -> servoPeriodNs。
2. startTaskHalStatusLoop 默认周期改为从同一个 INI 派生。
3. verify_run_feedback_loop.mjs 增加 STOP、ABORT、STEP、xyzbc-trt 对称 RUN 覆盖。
4. verify_run_feedback_loop.mjs 断言 taskHalStatusLoop.taskPeriodNs=10000000、
   servoPeriodNs=1000000，且 feedback sourceMode 不回退 fixture-line-playback。
5. verify_run_preconditions.mjs 增加 RUN gate 细粒度断言：
   machine off、not homed、manual mode、未打开 selected G-code。
6. working_run/README.md 增加 10 文档索引，并把下一步改为米尺度浏览器截图证据。
```

验证结果：

```bash
node web-rtcp-5axis-sim-plan/tests/node/verify_run_preconditions.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_run_feedback_loop.mjs
node web-rtcp-5axis-sim-plan/tests/node/verify_linuxcnc_task_hal_runtime.mjs
npm --prefix web-rtcp-5axis-sim-plan/app run build
npm --prefix web-rtcp-5axis-sim-plan/app run smoke:node
```

结果：

```text
全部通过。
run_preconditions_ini_profile_smoke=ok
run_feedback_status_loop_smoke=ok
linuxcnc_task_hal_runtime_smoke=ok
gmoccapy_static_build=ok
smoke:node 全部通过。
```

剩余项：

```text
1. 增加浏览器 desktop/mobile 米尺度截图证据。
2. 后续可补 G20/G21 中途切换浏览器端预览用例。
```
