Why:
- pumpingStation level-based control was calling MGC.handleInput(percent)
directly. handleInput expects canonical m³/s; a 1 % keep-alive arrived
as 1 m³/s ≈ 3600 m³/h, the dispatcher clamped to dt.flow.max and the
group ran at 100 %. The unit math already existed inside the set.demand
command handler — but only that handler could reach it.
What:
- New public method `async setDemand(value, unit='%')` on MachineGroup
(specificClass.js). Resolves the unit (`%` → interpolate against the
dynamic-totals envelope, absolute units → convert(value)) and calls
handleInput with canonical m³/s. Negative value remains the operator
stop-all signal. Single source of truth for the percent → m³/s rule.
- Refactor handlers.setDemand to parse the payload + apply mode gating
and then delegate to source.setDemand. Drops the local `convert` import
(now reached via the source).
- Update commands.basic.test.js mock with a setDemand shim that mirrors
the real method, so existing handleInput assertions still hold.
Packaging:
- Add .npmignore mirroring .gitignore plus dev-only trees (test/, wiki/,
CLAUDE.md, …) so the published tarball stays small.
- Extend .gitignore with the standard dev-artifact deny list.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>