---
title: Feature Intake — Toolhead Spindle Direction Selection
status: draft
requested_by: Antoine Letarte / Normand Fullum
generated_by: Nick / Hermes
project: P11-Polisher-Fullum
repo: polisher-control
source_truth: false
created: 2026-06-02
privacy: technical-only
---

# Feature Intake — Toolhead Spindle Direction Selection

## 1. Requested behavior

Normand wants the operator to select the toolhead/tool spindle rotation direction between clockwise and counter-clockwise.

The operator-facing control belongs in manual mode first, and the same field should be carried in future controller-job segments so program execution does not require a protocol/schema redesign.

## 2. Classification

- [x] Execution feature in `polisher-control`
- [x] Contract feature touching schemas/protocol/telemetry/logs
- [ ] Planning/intelligence feature that belongs upstream
- [ ] Safety/scope feature requiring Antoine approval beyond this explicit request

Rationale: the controller is not deciding polishing strategy. It is executing/logging an operator- or job-selected spindle direction. Because this changes the host↔Teensy payload and controller-job/log shape, it is also a contract feature.

## 3. Operator-visible behavior

- Manual UI exposes a spindle direction selector next to spindle RPM.
- Allowed values are:
  - `cw` — clockwise
  - `ccw` — counter-clockwise
- Physical convention: direction is viewed from above the toolhead looking down toward the mirror/tool contact.
- Default for existing/manual startup can be `cw` unless Antoine/Cédric chooses another default.
- Any direction change while running is logged as a timestamped setpoint event.

## 4. Affected layers

- Host controller: normalize/validate direction aliases and include direction in manual setpoints/log events.
- Teensy firmware: accept direction in `MANUAL_START`, `SETPOINT`, and future `SEGMENT_START`; map to AK60 command direction/sign convention.
- Host ↔ Teensy protocol: add `spindle_direction` / `commanded_spindle_direction` enum values `cw` / `ccw`.
- Telemetry channels: add `spindle_direction_setpoint` and `spindle_direction_actual` as recommended channels.
- Run/manual-session logs: record direction separately from RPM; RPM remains a non-negative magnitude.
- Machine capability profile: advertise `supported_spindle_directions: ["cw", "ccw"]`.
- Shared schemas: add direction fields to job/controller-job/run-log contracts.
- Tests: assert stable enum values, schema fields, and telemetry channel presence.

## 5. Safety implications

- Direction must not be inferred from signed RPM; use explicit enum plus non-negative RPM magnitude.
- Direction reversal while spindle is moving should be ramped/handled safely by firmware/AK60 implementation. The scaffold currently defines the contract; Cédric should decide whether live reversal is allowed directly or requires ramp-to-zero before applying the new direction.
- AK60 direction mapping is a commissioning item: firmware must be configured so UI `cw`/`ccw` matches physical observed tool rotation.

Safety decision:

- [x] No new optical strategy or autonomous behavior.
- [x] Implementation should add a safe reversal rule before hardware use.

## 6. Contract implications

- New controller-job segment field: `commanded_spindle_direction` enum `cw|ccw`.
- New planning job pass field: `spindle_direction` enum `cw|ccw`.
- New run-log commanded fields: `spindle_direction`.
- New capability field: `supported_spindle_directions`.
- New telemetry context channels: `spindle_direction_setpoint`, `spindle_direction_actual`.

## 7. Acceptance checks

- [x] Host contract tests for enum values and alias normalization.
- [x] Schema field test for `commanded_spindle_direction`.
- [x] Telemetry channel test for direction channels.
- [ ] Firmware compile/build check once Cédric maps this into Teensy/AK60 code.
- [ ] Bench test confirms UI `cw` physically rotates clockwise by the documented convention.
- [ ] Bench test confirms UI `ccw` physically rotates counter-clockwise by the documented convention.
- [ ] Bench test confirms live reversal behavior is safe or blocked until spindle reaches zero.

## 8. Open questions

- Cédric: confirm the AK60 command/direction mapping and whether live direction reversal requires ramp-to-zero.
- Antoine/Normand: confirm the physical viewing convention: current draft uses “viewed from above the toolhead looking down toward the mirror/tool contact.”

## 9. Implementation notes

Initial scaffold update created on branch `docs/nick-llm-context-20260602`:

- `host/polisher_control/contracts.py`
- `host/polisher_control/telemetry_channels.py`
- `tests/test_spindle_direction_contract.py`
- `shared/schemas/*.schema.json`
- `shared/schemas/examples/*.json`
- `shared/machine/fullum-alpha.capabilities.v1.json`
- affected docs/checklists
