---
phase: 14
slug: usb-serial-foundation-and-led-control
status: draft
nyquist_compliant: false
wave_0_complete: false
created: 2026-04-18
---

# Phase 14 — Validation Strategy

> Per-phase validation contract for feedback sampling during execution.

---

## Test Infrastructure

| Property | Value |
|----------|-------|
| **Framework** | none (no unit-test framework in project) |
| **Config file** | none — manual + hardware-visible smoke plus spike-local `harness.cpp` for pure functions |
| **Quick run command** | `"C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe" --build build --config Release` |
| **Full suite command** | Build + manual CLI smoke against attached WLED ESP32-C3 hardware |
| **Estimated runtime** | ~30s build, ~2min manual hardware smoke |

---

## Sampling Rate

- **After every task commit:** Run Release build (must compile clean)
- **After every plan wave:** Build + CLI smoke (`led fill`, `led set`, `led off`, ceiling clamp)
- **Before `/gsd-verify-work`:** Full manual smoke green against hardware
- **Max feedback latency:** ~60s (build) / manual for hardware behavior

---

## Per-Task Verification Map

| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
| 14-01-01 | 14.1 | 1 | LHWD-01 | — | N/A | manual | spike harness `'v'` round-trip over COM port | ❌ W0 | ⬜ pending |
| 14-01-02 | 14.1 | 1 | LHWD-02 | — | N/A | manual | enumerate COM ports, filter by VID/PID | ❌ W0 | ⬜ pending |
| 14-01-03 | 14.1 | 1 | LCTL-01 | — | N/A | harness | Adalight encoder pure-function output match | ❌ W0 | ⬜ pending |
| 14-01-04 | 14.1 | 1 | LCTL-03 | — | brightness clamp | harness | ceiling-clamp pure-function never exceeds config | ❌ W0 | ⬜ pending |
| 14-02-01 | 14.2 | 2 | LHWD-03 | — | N/A | manual | unplug/replug hotplug via `RegisterDeviceNotification` | ❌ W0 | ⬜ pending |
| 14-02-02 | 14.2 | 2 | TRNS-01 | — | N/A | build | writer thread + reconnect loop compiles & links | ✅ | ⬜ pending |
| 14-02-03 | 14.2 | 2 | LCTL-01, LCTL-02 | — | N/A | manual | `led fill 255 0 0` → all 10 LEDs red | ❌ W0 | ⬜ pending |
| 14-02-04 | 14.2 | 2 | LCTL-03 | — | clamp | manual | CLI sends 255, hardware shows ceiling (50/255) | ❌ W0 | ⬜ pending |
| 14-02-05 | 14.2 | 2 | LCTL-04 | — | N/A | manual | `led set 3 0 255 0` → only LED 3 green | ❌ W0 | ⬜ pending |
| 14-02-06 | 14.2 | 2 | LCTL-05 | — | shutdown safety | manual | stop SteamVR → all LEDs off within 1s, no residual glow | ❌ W0 | ⬜ pending |
| 14-02-07 | 14.2 | 2 | DIAG-02 | — | N/A | manual | `beyond_prox_ctl.exe led status` returns connection state | ❌ W0 | ⬜ pending |

*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*

---

## Wave 0 Requirements

- [ ] `src/test/led_harness.cpp` — spike-local pure-function harness (Adalight encoder, hex parser, ceiling clamp)
- [ ] Manual test script `.planning/phases/14-usb-serial-foundation-and-led-control/smoke.md` — repeatable hardware smoke steps
- [ ] No framework install — project has no test framework and scope-creep avoided per CONTEXT.md

---

## Manual-Only Verifications

| Behavior | Requirement | Why Manual | Test Instructions |
|----------|-------------|------------|-------------------|
| All 10 LEDs light red | LCTL-01, LCTL-02 | Requires physical hardware | Run `beyond_prox_ctl.exe led fill 255 0 0`, visually confirm |
| Ceiling clamp enforcement | LCTL-03 | Visual hardware verification | Set ceiling 50, send 255, confirm LEDs no brighter than ceiling |
| Individual LED addressing | LCTL-04 | Visual | `led set 3 0 255 0`, confirm only LED index 3 green |
| Auto-off on driver unload | LCTL-05 | Driver lifecycle + hardware | Stop SteamVR, confirm LEDs dark within 1s |
| Hotplug recovery | LHWD-03 | USB replug required | Unplug WLED mid-session, replug, confirm reconnect + commands resume |
| COM port discovery | LHWD-01, LHWD-02 | Requires attached device | Observe log output of enumerated ports + VID/PID match |
| VRSettings read | LCTL-03 | Requires SteamVR config file | Edit `steamvr.vrsettings`, confirm ceiling/COM override applied |
| Residual glow prevention | LCTL-05 | Visual | Crash driver (kill process), confirm LEDs off via WLED watchdog/heartbeat |

*Camera stream (https://vdo.ninja/?view=JYMW97gq) may be enabled by user for agent-side visual verification — ask before relying on it.*

---

## Validation Sign-Off

- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify (harness covers spike; main-impl is manual-hardware-bound by necessity)
- [ ] Wave 0 covers all MISSING references
- [ ] No watch-mode flags
- [ ] Feedback latency < 120s (build) / manual hardware
- [ ] `nyquist_compliant: true` set in frontmatter

**Approval:** pending
