# Architecture ## Runtime split ### Host controller — Python on RPi/PC Responsibilities: - operator workflow and manual-mode UI integration; - state machine orchestration; - controller-job intake validation; - geometry gate; - setpoint command stream; - telemetry capture; - logs, manifests, hashes, status file; - slow watchdogs and data export. ### Teensy firmware — C++ on Teensy 4.x Responsibilities: - inner loop around ~1 kHz; - KWR75B-CAN F/T receive path; - encoder acquisition; - force PID output; - table/spindle/actuator command outputs; - fast safety checks; - heartbeat supervision; - telemetry frames at >=100 Hz; - ACK/NACK and event/fault frames. ## State machine Current accepted state names: ```text IDLE JOB_LOADED READY RUNNING PAUSED ABORTING COMPLETED ABORTED FAULTED MANUAL ``` Important rules: - `FAULTED` exits only through explicit operator reset. - `JOB_LOADED -> READY` requires operator acknowledge. - `IDLE -> MANUAL` is allowed only with no job loaded. - Illegal transitions are errors and events, never silent ignores. - Manual mode uses the same safety/interlocks as job mode. ## Manual mode sequence 1. Machine starts in `IDLE`. 2. Operator opens Manual Mode. 3. Host enforces the geometric gate. 4. Host sends `MANUAL_START` to Teensy. 5. Teensy ACKs or NACKs with a machine-readable reason. 6. Host sends live `SETPOINT` updates. 7. Teensy emits telemetry and events. 8. Operator stops; host sends `MANUAL_STOP`. 9. Host writes manual-session log and artifacts.