You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
F-25: Physical knobs not gated on the link; optimistic update outlives a failed send #28
Severity: MEDIUM · Effort: Small · Batch: 4 · Status: Code done in #21 (1b8767b), awaiting bench verification
Found in the second full review of the firmware. Recorded with the rest of the pass (F-19…F-44) in docs/REVIEW_REMEDIATION_PLAN_2.md, which is where its status is kept.
Description
CLAUDE.md says K1/K2 are disabled while the transport is disconnected, but only the touch path
checks: the encoder path (AppController → ThrottleController::onKnobRotation) does not. The
model is also updated before the send, and sendSpeedCommand ignores the result, so a refused
command leaves the display ahead of the loco. The orchestrator refuses manual commands while offline; the display creeps to 40 with the loco at 0, and the first click afterwards sends 44.
Plan
onKnobRotation and the CONTROLLING branch of onKnobPress refuse when the backend is not
connected.
Roll the model back to the pre-command value when the send fails, and repaint.
Files:ThrottleController.cpp, tests
Acceptance Criteria
A knob turn or press while disconnected changes nothing (knobInputAllowed, in the
controller, so the physical encoders are covered).
A failed send rolls the model back — unless a transport report has landed since.
The orchestrator's case is a refused command, not a failed send: it answers ERROR. OrchestratorBackend now re-seeds every assigned throttle from the layout's last
reported state on any ERROR (the F-20 cache makes that possible).
Unit tests test_controller_knob_ignored_while_disconnected, test_controller_failed_send_rolls_back and test_orch_backend_refusal_reseeds_from_layout_state pass on the board (they compile).
Bench: with the orchestrator offline, turn a knob; the display returns to the layout's
speed. Pull the WiFi and turn a physical knob; nothing moves on screen.
Activity