Consumer half of the abort-token mechanism added in generalFunctions
state.js. executeSequence captures host.state.sequenceAbortToken at
entry, then re-checks before every state transition and after the
optional ramp-down. If MGC (or any external caller) bumps the token
mid-sequence, the loop bails out cleanly — no more barge-through where
a pre-empted shutdown advances through stopping → coolingdown after a
fresh demand has already engaged the pump.
Without this the MGC rendezvous planner can't reliably re-dispatch a
pump that's mid-shutdown: the new flowmovement claims the gate, but
the old shutdown's for-loop keeps running on microtasks and steps the
FSM into idle/off underneath it.
Also: wiki regen following the same visual-first 14-section template as
the other EVOLV nodes — Reference-{Architecture,Contracts,Examples,
Limitations}.md split with _Sidebar.md index.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.9 KiB
Reference — Limitations
Note
What
rotatingMachinedoes not do, current rough edges, and open questions. Open items live in.agents/improvements/IMPROVEMENTS_BACKLOG.mdin the superproject.
When you would not use this node
| Scenario | Use instead |
|---|---|
| A passive non-return / check valve (no motor) | valve — no curve, no FSM-driven motor. |
| A valve actuator (motorised, no characteristic curve) | valve (and valveGroupControl if grouped). |
| A group of 2 + pumps load-sharing on a header | machineGroupControl — instantiate this as a child. |
| A curve-less asset | Predictions degrade to zero, drift becomes meaningless, status badge falls into predictionQuality: 'invalid'. There is no fallback model. |
| A compressor with significant gas compressibility | Predictor uses an incompressible-flow curve; output is qualitatively right but quantitatively biased. Tracked. |
Known limitations
Single-side pressure degrades silently
pressureSelector.getMeasuredPressure accepts only-upstream or only-downstream readings as a fallback when the differential is unknown. It logs a warn (Using downstream pressure only for prediction: …. Prediction accuracy is degraded; inject upstream pressure too.) but proceeds. The predictor uses the absolute pressure as a surrogate differential, which can materially bias flow predictions under varying suction conditions. The warn is one-shot per state transition, not per tick — it can be missed in long-running deployments. Tracked.
Multi-parent registration
childRegistrationUtils accepts registration under multiple parents. The pump emits child-register messages to each, and parents listen in parallel. Teardown ordering (parent gone first vs pump gone first) is not test-covered; observed behaviour in production is "fine, mostly". If you wire one pump to two MGCs and remove one MGC mid-deployment, the pump's listener set may keep a stale reference. Open question.
data.simulate-measurement doesn't clear stale values
If you toggle a virtual pressure off (stop sending the inject), the last-known value persists in the MeasurementContainer. There is no TTL and no explicit clear topic. Workaround: send value: null or 0 explicitly. Tracked.
execSequence legacy umbrella
The execSequence topic (with payload.action = "startup" | "shutdown") is kept alive for legacy flows. The handler demuxes to the canonical topic; both emit a one-time deprecation warning. Scheduled for removal in a later phase. Use cmd.startup / cmd.shutdown instead.
Drift confidence collapses on long pressure-source outages
predictionHealth.refresh reduces predictionConfidence to 0 when no pressure source has produced a reading in > 30 s. The quality string flips to invalid — downstream consumers should treat this as "predictor is offline, ignore values" rather than "predictor is broken". The recovery is automatic: as soon as a pressure measurement lands, health climbs back. Open question whether to model this as a discrete "stale" quality state instead.
state stays in residue after a routine abort
abortCurrentMovement with default options (the kind MGC fires) does not auto-transition the FSM back to operational. The pump stays parked in accelerating / decelerating until the next moveTo arrives — at which point the residue handler in state.moveTo runs the transition synchronously. By design (a previous version auto-transitioned and created a bounce loop where every tick aborted, returned, re-moved, aborted again). See the comment in state.js moveTo line 76 for the historical detail.
Editor cosmetics don't reflect asset derivation
The editor form still has visual sections for supplier / category / type even though the registry derives them. They're read-only and informational; some fields render as blank until you select a model. Cosmetic; the registry is the source of truth.
Open questions (tracked)
| Question | Where it lives |
|---|---|
Should the predictor use an explicit "stale" quality state instead of collapsing to invalid when pressure data dries up? |
Internal — not yet ticketed |
| Multi-parent teardown ordering | Internal |
Add an explicit data.clear-simulated-measurement topic for sim cleanup |
Internal |
| Compressor / gas-flow curve handling | Internal (long-term) |
Phase 7 removal of execSequence umbrella + legacy aliases |
Internal |
| Curve loader robustness: warn / refuse mismatched curve units instead of best-effort normalising | OPEN_QUESTIONS.md (rotatingMachine entry) |
Migration notes
From pre-AssetResolver
Old flows saved with supplier, category, or assetType fields will throw on deploy:
rotatingMachine: legacy asset field(s) [supplier, category] are saved on this node.
After the AssetResolver refactor these are derived from the model id.
Open the node in the editor, re-select the model, and save to migrate.
The fix is mechanical: open each rotatingMachine node, re-pick the model from the asset menu, save. No data is lost — the registry has the same supplier / category / type the old flow carried.
From pre-sequence-abort-token
Before 2026-05-15 a mid-decel re-engage was a race — sometimes the shutdown's for-loop won and parked the pump at idle with an orphaned delayedMove. With the sequenceAbortToken mechanism in state.js + sequenceController.js (from 394a972 onward), the new-dispatch's abortCurrentMovement always wins: the shutdown's for-loop breaks out before its next transition.
If you have an integration test that relied on the older "shutdown always completes" behaviour, expect to see Sequence 'shutdown' interrupted ... by external abort warnings instead. That's the intended new state.
From setpoint topic name (pre-canonical)
The old setpoint topic without a set. prefix has been retired. Use set.setpoint (alias execMovement) for control-% setpoints and set.flow-setpoint (alias flowMovement) for flow setpoints.
From execMovement payload shape change
Legacy payloads were {source, action: "execMovement", setpoint: number}. The current shape is the same minus action (the handler dispatches via topic). Both are accepted.
Related pages
| Page | Why |
|---|---|
| Home | Intuitive overview |
| Reference — Contracts | Topic + config + child filters (alias map at the end) |
| Reference — Architecture | Code map, FSM (including sequence-abort token), prediction + drift |
| Reference — Examples | Shipped flows + debug recipes |
| machineGroupControl — Limitations | Where the parent's planner currently bypasses priority mode |