From b7c40b0ddc526ccffa221d6b9d42b8a2b4a7d478 Mon Sep 17 00:00:00 2001 From: Rene De Ren Date: Fri, 8 May 2026 11:47:17 +0200 Subject: [PATCH] equalFlowControl: mirror the optimalControl dispatch reorder The priority-control codepath had the same stale dispatch shape that caused the live deadlock in optimalControl: only handling idle and operational states, and chaining flowmovement after execsequence startup. Aligns it with the optimalControl fix so a future mode switch to prioritycontrol doesn't reintroduce the bug. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/specificClass.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/specificClass.js b/src/specificClass.js index ed528f7..cd78b67 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -1121,16 +1121,18 @@ class MachineGroup { this.logger.debug(this.machines[machineId].state); const currentState = this.machines[machineId].state.getCurrentState(); - if (flow <= 0 && (currentState === "operational" || currentState === "accelerating" || currentState === "decelerating")) { + // Same dispatch shape as optimalControl — see the comment + // there for the rationale. flowmovement BEFORE startup so + // concurrent retargets can update delayedMove without a + // stale chained flowmovement overwriting it after startup. + if (flow > 0) { + await machine.handleInput("parent", "flowmovement", this._canonicalToOutputFlow(flow)); + if (currentState === "idle") { + await machine.handleInput("parent", "execsequence", "startup"); + } + } else if (currentState === "operational" || currentState === "accelerating" || currentState === "decelerating") { await machine.handleInput("parent", "execsequence", "shutdown"); } - else if (currentState === "idle" && flow > 0) { - await machine.handleInput("parent", "execsequence", "startup"); - await machine.handleInput("parent", "flowmovement", this._canonicalToOutputFlow(flow)); - } - else if (currentState === "operational" && flow > 0) { - await machine.handleInput("parent", "flowmovement", this._canonicalToOutputFlow(flow)); - } })); } catch (err) {